经常听人问Camera开发中,各种变形问题,今天有空就在此梳理总结下。
三个尺寸:
1、Surfaceview的尺寸
Surfaceview是用来预览Camera的,当它全屏时就是Screen的大小。
2、Picturesize的尺寸
这是拍照后的PictureSize尺寸。
3、Previewsize的尺寸
这是预览时帧数据的尺寸。
三种变形:
1、预览画面的物体长宽失真。原因是Surfaceview和Previewsize的长宽比率不一致,就会导致预览画面上失真。因为camera在显示时会将预览帧数据缩放成Surfaceview大小,当比率不一致必然会物体变形。至于这个缩放算法可能不同手机会有区别。
2、拍照后照片上物体变形。
3、点击拍照瞬间,预览画面上会突然变形然后恢复到正常预览。
2、3两种变形都是因为Previewsize和Picturesize的长宽比率不一致所致。总之一句话,为了保证图片不是真,要保证预览Surfaceview、Previewsize、Picturesize的长宽比率要一直。如果Surfaceview是全屏的话,要获取屏幕长和宽得到比率。
为此我写了一个工具类,获得合适的Picturesize和Previewsize,名字为:MyCamPara.java。
package org.yanzi.util; import java.util.Collections; import java.util.Comparator; import java.util.List; import android.hardware.Camera; import android.hardware.Camera.Size; import android.util.Log; public class MyCamPara { private static final String tag = "yan"; private CameraSizeComparator sizeComparator = new CameraSizeComparator(); private static MyCamPara myCamPara = null; private MyCamPara(){ } public static MyCamPara getInstance(){ if(myCamPara == null){ myCamPara = new MyCamPara(); return myCamPara; } else{ return myCamPara; } } public Size getPreviewSize(List<Camera.Size> list, int th){ Collections.sort(list, sizeComparator); int i = 0; for(Size s:list){ if((s.width > th) && equalRate(s, 1.33f)){ Log.i(tag, "最终设置预览尺寸:w = " + s.width + "h = " + s.height); break; } i++; } return list.get(i); } public Size getPictureSize(List<Camera.Size> list, int th){ Collections.sort(list, sizeComparator); int i = 0; for(Size s:list){ if((s.width > th) && equalRate(s, 1.33f)){ Log.i(tag, "最终设置图片尺寸:w = " + s.width + "h = " + s.height); break; } i++; } return list.get(i); } public boolean equalRate(Size s, float rate){ float r = (float)(s.width)/(float)(s.height); if(Math.abs(r - rate) <= 0.2) { return true; } else{ return false; } } public class CameraSizeComparator implements Comparator<Camera.Size>{ //按升序排列 public int compare(Size lhs, Size rhs) { // TODO Auto-generated method stub if(lhs.width == rhs.width){ return 0; } else if(lhs.width > rhs.width){ return 1; } else{ return -1; } } } }
1,是个单例模式类。调用示例:
Size pictureS = MyCamPara.getInstance().getPictureSize(pictureSizes, 800); myParam.setPictureSize(pictureS.width, pictureS.height);
3,通过equalRate(Size s, float rate)保证Size的长宽比率。一般而言这个比率为1.333/1.7777即通常说的4:3和16:9比率。
4、在getPreviewSize()函数里增加判断if((s.width > th) && equalRate(s, 1.33f)),除保证比率外,还保证用户需要设置的尺寸宽度最小值。这个大家根据需要随便改。
如果您觉得笔者在认真的写博客,请为我投上一票,谢谢大家。
CSDN2013博客之星评选: