这几天写了个相机,遇到问题比较多,开发中遇到各种坑,下面做一个简单的总结.
1.开发中遇到的比较多的问题是预览变形的问题。(我选择尺寸是根据屏幕的宽高来做)
关于变形这个问题比较常见了,各种解决方案也很多,不过遵循一点原则很重在,SurfaceView的视图宽高比——相机预览的时候的宽高比——相机拍出的相片的宽高比要保持一致。
这里处理的方式多种
a.可以选取合适的照片尺寸后再取更改预览和surfaceView的尺寸比例.
b.也可以选取预览和图片尺寸按照已有的SurfaceView尽行选取,总之要保持三个尺寸比值一直,才能保证预览不变形。
2.拍出的照片不清晰
拍照不清楚一般是因为照片的尺寸选取不合理,我这是因为预览是全屏的,所以照片尺寸选择是也参照屏幕比例来做的。这样也是为了保证预览和拍出的照片一致
3.关于自动对焦的问题
对焦是根据传感器的变化来进行监听的,实时的去对焦。
下面是部分代码片段:
选取尺寸的算法,首先是根据比例和数值去选择,没有合适比例的在根据数值来选择。(网上用的比较多的算法)
private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;//预览标准比值
if (sizes == null)
return null;
Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
下面是一些具体的流程:
首先拿到所有支持的尺寸,并在里面选出一个和手机屏幕尺寸最接近的尺寸。
List<Size> sizes = parameters.getSupportedPreviewSizes();//支持预览尺寸
Size optimalSize = getOptimalPreviewSize(sizes, screenHeight, screenWidth);
//设置一个预览的尺寸给相机
parameters.setPreviewSize(optimalSize.width, optimalSize.height);
//部分手机预览的尺寸达不到全屏,在保证比例的情况下进行放大道全屏,预览尺寸和surface保持比例一致
//这段代码主要是在适配魅族和华为手机时候,发现魅族的预览大于屏幕的尺寸,华为的潜质涉嫌小于屏幕尺寸(前置的预览尺寸列表和后置不一致)。
if (optimalSize.height < screenWidth && optimalSize.width < screenHeight && equalRate(optimalSize, ScreenRatio)) {
framelayoutPreview.setLayoutParams(new FrameLayout.LayoutParams(screenWidth, screenHeight));
} else {
if (optimalSize.height > screenWidth && optimalSize.width > screenHeight && equalRate(optimalSize, ScreenRatio)) {
framelayoutPreview.setLayoutParams(new FrameLayout.LayoutParams(screenWidth, screenHeight));
} else {
framelayoutPreview.setLayoutParams(new FrameLayout.LayoutParams(optimalSize.height, optimalSize.width));
}
}
//下面设置拍摄出的图片的尺寸
sizes = parameters.getSupportedPictureSizes();//支持图片尺寸
optimalSize = getOptimalPreviewSize(sizes, optimalSize.width, optimalSize.height);
parameters.setPictureSize(optimalSize.width, optimalSize.height);
上面选取尺寸是按照一个规则来,保证尺寸最大一致性。
有问题欢迎交流。
下面补充一点常见问题。
1.如果出现拍照预览时候感觉景物被拉的很近?
应该是你选择的预览尺寸过小,但是又强行将预览设置填充屏幕所致。
2.如果照片不清晰?
应该是设置图片的size过小导致
3.如果出现预览变形?(长宽有拉伸的现象)
检查是否设置SurfaceView出现问题,主要是SurfaceView的长宽和图片的不一致, 图片 是 宽 > 高 surface 是 宽 < 高,这里值得注意一下。
----------------------------------
有新的问题会即时补充。