camera2 拍照超时_Android Camera2采坑记录

问题1 相机预览画面变形

造成原因:

画面显示空间的长宽比例与相机预览的分辨率比例不一致

解决方案:

根据SurfaceView的长宽比例选择合适的相机分辨率,并调整SurfaceView的显示比例(因为相机预览的分辨率是固定的那几组,而你无法百分百确定选择相机的分辨率会和你SurfaceView的比例一致,所以,选择完相机预览分辨率后,你还得调整显示画面的比例)

/**

* 选择合适的预览尺寸

*

* @param choices

* @param textureViewWidth

* @param textureViewHeight

* @return

*/

private Size chooseOptimalSize(Size[] choices, int textureViewWidth, int textureViewHeight) {

//先查找preview中是否存在与surfaceview相同宽高的尺寸

for (Size option : choices) {

if ((option.getWidth() == textureViewWidth) && (option.getHeight() == textureViewHeight)) {

return option;

}

}

// 得到与传入的宽高比最接近的size

float reqRatio = ((float) textureViewWidth) / textureViewHeight;

float curRatio, deltaRatio;

float deltaRatioMin = Float.MAX_VALUE;

Size retSize = null;

for (Size size : choices) {

curRatio = ((float) size.getWidth()) / size.getHeight();

deltaRatio = Math.abs(reqRatio - curRatio);

if (deltaRatio < deltaRatioMin) {

deltaRatioMin = deltaRatio;

retSize = size;

}

}

return retSize;

}

问题2 Camera2手动点击聚焦失效

问题详情:参考Camera2-master项目手动点击聚焦,设置完CaptureRequest.Builde所需要手动聚焦的参数后,使用CameraCaptureSession.setRepeatingRequest()请求相机聚焦于某一区域,小米手机上面测试失效。然后并不是所有的设备都会失效,我所使用的另一台华为mate9设备能够正常聚焦。

代码如下:

//List of metering areas to use for auto-exposure adjustment. 自动曝光

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions);

//传感器所需要捕获的区域

mCaptureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion);

// float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);

// float num = (((float) 1) * minimumLens / 100);

// mCaptureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.0f);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);

updatePreview(mCameraCaptureSession);

/**

* 更新相机预览

*

* @param session

*/

private void updatePreview(CameraCaptureSession session) {

try {

session.setRepeatingRequest(mCaptureRequestBuilder.build(), null, mChildHander);

} catch (CameraAccessException e) {

e.printStackTrace();

} catch (IllegalStateException e) {

//CameraDevice was already closed

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

造成原因

具体的原因还没有找到,查看谷歌官方文档,比较了一下setRepeatingRequest 和capture方法的区别,一个是他们的优先级不一样,后者要高于前者,后来再仔细想想,请求聚焦应该只是某一刻的时候发生的事情,也不应该是连续的事情,所以使用capture还是挺合理的。

解决方案:

在谷歌上找到关于AF的一些问题的方法,尝试使用CameraCaptureSession.capture()方法去请求需要手动聚焦的区域,在小米手机上面测试,效果显著,问题解决。

//List of metering areas to use for auto-focus 用来自动对焦的测量面积列表

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, mAFRegions);

//List of metering areas to use for auto-exposure adjustment. 自动曝光

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, mAERegions);

//传感器所需要捕获的区域

mCaptureRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRegion);

// float minimumLens = mCameraCharacteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE);

// float num = (((float) 1) * minimumLens / 100);

// mCaptureRequestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.0f);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);

mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START);

try {

mCameraCaptureSession.capture(mCaptureRequestBuilder.build(),null,mChildHander);

} catch (CameraAccessException e) {

e.printStackTrace();

}

你可能感兴趣的:(camera2,拍照超时)