腾讯优测 总监 雷彬
【引言】
如果你不想随时扛着单反和三脚架去抓拍生活的点滴故事,却仍然希望能拍到质量很高效果很好的照片。如果你不想因为拍照的失误而错过重要的瞬间。如果你手上有一部安卓手机,并且安装了一款非常不错的相机app,你的愿望就能实现。
用手机记录生活和身边的风景,已经渐渐成为了一种生活方式。随着手机用户对拍照质量的要求日益提高,各个手机厂商在相机系统上更是大做文章,竞争激烈。因此相机系统的各种机型适配问题,可以说是奇葩不断,匪夷所思,攻城狮们都惊呆了!
本文就讨论一下如何提升android相机产品质量,为用户拍出高质量的照片。
【Camera系统原理及Android相机成像】
1.Android camera系统介绍
对于做相机产品的攻城狮来说,距离我们最近的相机相关的部分就是Android Camera系统了。我们就先介绍一下我们又爱又恨的Android Camera系统。
(1)Camera系统结构
Andriod 照相机的基本层次结构
Andriod Camera 系统结构
自下而上,Camera系统分成了以下几个部分:
(1)摄像头驱动程序
(2)Camera硬件抽象层
(3)Camera服务部分
(4)Camera的本地框架代码
(5)Camera的JNI代码
(6)Camera系统的java类
(2)Camera系统调用流程
Camera系统的几个常用功能:
(1)预览preview
(2)视频获取recording
(3)拍照takePicture
(4)参数设置
而图像处理的重点在于预览,拍照和参数设置,下图是调用流程。
(3)Camera系统数据流
当图像数据出现问题的时候,我们需要知道数据流的来龙去脉,找到关键模块,查出问题的根源。
图片预览的数据流
拍照的数据流
2.Android相机成像原理:
接下来我们讨论一下硬件的成像原理,这一部分是决定拍照质量的基础。
景物通过镜头生成的光学图像投射到图像传感器表面上,然后转为电信号,经过ADC(模数转换)转换后变为数字图像信号,再送到数字信号处理芯片(DSP)中加工处理,再通过IO接口传输到CPU中处理,通过DISPLAY就可以看到图像了。
在这部分,我们常用的能够提高照片质量的功能包括:对焦,曝光,感光,测光,白平衡,对比度,实时滤镜,全景照片,方向矫正等。要想解决好机型适配问题,提高产品质量,从而提高照片质量,需要在以上几个方面要做好功课。
【相机系统的适配问题】
通过对相机适配问题的搜集和整理总结,我们发现出现问题的原因大致是来源于以下几个方面。
1.camera系统
在android中Google实现了与硬件无关的所有代码,但是与硬件密切相关的硬件抽象层却没有也无法提供,对于不同设备底层硬件是千变万化的,不可能提供统一的硬件驱动以及接口实现,只能提供标准的接口,因此硬件提供商需要自己开发设备驱动,并去实现android框架提供的接口。这样就导致同样的相机产品,在不同机型上拍照效果却不一样。甚至某些特殊功能,硬件不支持。比如有些低端机型的摄像头不支持自动对焦,不支持测光。从而这些硬件不支持的API无法调用,或者返回值特殊。头疼的是几乎所有厂商都会根据自己的需要改变camera系统。
2.andriod版本
Andriod不同版本的camera类的API会有改变,同时开源库也会不同。 最新的andriod4.3版本已经标配opengles3.0。和过去使用了很久的opengles2.0相比,3.0增加了更多的高端大气上档次的纹理。因而对机器的性能要求也更高。
3.机型的硬件配置
不同价位,不同厂商的机型,硬件配置大相径庭。这里说的硬件配置不是指摄像头,而是指处理图像要用到的CPU,GPU,传感器等等。比如性能不好的GPU或者没有GPU的机型处理数据时,速度达不到默认的帧率要求时,就会出现跳帧,数据覆盖等情况。全景拍照和人脸识别都会出现类似的问题。而传感器则涉及到照片方向矫正问题。
【解决适配问题,提高照片质量】
以下是用户在拍照时的操作过程已经容易出现的问题。
要提高照片质量,我们可以从实际的拍照过程中对焦,曝光,感光,测光,白平衡,场景模式,方向矫正等角度入手。解决相关的适配问题,提高产品质量。
大连腾讯优测项目组对相机系统相关的机型适配bug进行了搜集和整理。接下来举几个例子说明。
1.手机无闪光灯,但是调用API查询闪光灯状态时仍然返回有闪光灯的状态。
奇葩处处有,相机特别多。三星 i5508和天语T619使用Android官方API getSupportedFlashModes( )判断是否有闪光灯时返回结果不准确。
解决策略:
PackageManager pm=(PackageManager)getSystemService(Context.PackageManager);
FeatureInfo[] features=pm.getSystemAvailableFeatures();
for(FeatureInfo f : features)
{
logcat.d( f.name);
if(PackageManager.FEATURE_CAMERA_FLASH.equasl( f.name))
{
//代码
}
}
2.HTC部分机型拍照方向默认为横屏,竖屏拍照时,照片方向错误。
这个奇葩问题在多个机型中都会出现。具有一定的普遍性。
解决策略:
(1)对于能够从图像数据中找到旋转角度的机型。利用ExifInterface取到图片数据中的拍摄方向,返回的值为1,3,6,8 。1为与默认拍摄方向相符不需要旋转,3为再默认拍摄方向向右旋转90度,6为再默认拍摄方向向左旋转90度,8为再默认拍摄方向旋转180度,代码如下:
ExifInterface ef = new ExifInterface(图片存储位置);
String sModel=ef.getAttribute(ExifInterface.TAG_ORIENTATION);
int rotate = 0;
switch (Integer.valueOf(sModel)){
case 3:
rotate = 180;
break;
case 6:
rotate = 90;
break;
case 8:
rotate = -90;
break;
}
// 创建操作图片用的matrix对象
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
Bitmap resizedBitmap = Bitmap.createBitmap(myBitmap, 0, 0, myBitmap.getWidth(), myBitmap.getHeight(), matrix, true);
这种方法弊端是比较消耗内存
(2)对于无法从图像数据中找到旋转角度的。去除设置路径语句,onActivityResult(int requestCode, int resultCode, Intent data)回调方法中,对data做非空判断,data不为空,通过对data取值可得到图片。图片方向正确。
(3)以上两种方法都不奏效的。需要添加图片方向确认界面。并且记住用户设置的旋转角度。
3.部分手机设置夜间场景时不支持Camera.Parameters.SCENE_MODE_NIGHT参数
部分手机设置夜间场景时不支持Camera.Parameters.SCENE_MODE_NIGHT参数,如魅族M040就只能用“night-shot”进行夜间场景的设置,如果调用Camera.Parameters.SCENE_MODE_NIGHT进行设置时会抛出异常导致程序crash。
解决策略:
用Camera.Parameters.getSupportedSceneModes()方法获得手机可以设置的全部场景参数,然后进行对比,如果“night”在该集合中再进行相关设置。
4.相机Parameter对象中感光度API: parameter.get(“iso-values”)返回集合为null, 导致无法通过该方法获得的集合值进行ISO感光度的设置。
三星 9300手机在framework层中的android.hardware.Parameters中不提供iso支持值得获得。
解决策略:
在调用这个集合值前会进行空值判断,如if(parameter.get(“iso-values”).isEmpty())
9300不用调用该方法获取,9300的可支持设置的值有:auto,100,200,400,800;
即可调用Parameters.set(“iso”,”auto”);
Parameters.set(“iso”,”100″);
Parameters.set(“iso”,”200″);
Parameters.set(“iso”,”400″);
Parameters.set(“iso”,”800″);
其中的任一方法进行感光度的设置。
【总结】
相机系统在机型适配时问题是比较多的。尤其是做相机app的时候,要考虑周全camera系统,andriod版本,机型硬件配置等方面会出现的问题。不过这些恼人的问题,现在有了更好的解决方案了。
腾讯优测是专业的移动云测试平台,为应用、游戏、H5混合应用的研发团队提供产品质量检测与问题解决服务。不仅在线上平台提供自动化兼容性测试、云手机远程租用与调试、漏洞分析、自动化测试工具Xtest等多种质量检测工具,更为VIP客户配备了专家团队提供定制化综合测试解决方案。