实现特点
- 不需要自动对焦
- 正常触发闪光灯flash
- 复用
CaptureRequest.Builder
, 参数完全一致
流程
- 按照常规方式打开预览
- 设置好相应的全局变量:
-
CameraDevice
的mCamera
-
CameraCaptureSession
的mCaptureSession
-
CaptureRequest.Builder
的mPreviewRequestBuilder
-
ImageReader
的mImageReader
等
-
- 定义一个类似
takePicture()
的开始拍照方法 - 不用对焦, 直接开始拍照, 调用类似
captureStillPicture()
的方法 - 拍摄前, 如果需要闪光的, 需要设置
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
这条语句会触发闪光的开启动作
- 添加拍摄图片的输出
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
- 设置当前的拍摄意图
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
这条设置页会影响到闪光的正常开启. 如果不需要闪光灯的话, 设置了也没事.
- 设置图片的方向
因为物理相机的镜头方向可能和手机的朝向不一致(手机倒着拿), 所以设置这个是确保拍摄出来的图片永远是正向的
int sensorOrientation = mCameraCharacteristics.get(
CameraCharacteristics.SENSOR_ORIENTATION);
mPreviewRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,
(sensorOrientation +
mDisplayOrientation * (mFacing == Constants.FACING_FRONT ? 1 : -1) +
360) % 360);
- 停止画面预览
mCaptureSession.stopRepeating();
也可以不调用这条, 不停止画面. 不过这样会出现闪光灯闪烁2次的问题.
- 开始拍照
mCaptureSession.capture(mPreviewRequestBuilder.build(),
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
//移除输出到ImageReader, 不移除的话,会造成拍照停不下来的问题
mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
//恢复相机预提为预览
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_PREVIEW);
try {
//不加这句话, 闪光灯无法正常工作, 如果不适用闪光等, 可以不加
mCaptureSession.capture(mPreviewRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}, null);
- 结束了.
完整部分代码
void captureStillPicture() {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
try {
mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
// Calculate JPEG orientation.
@SuppressWarnings("ConstantConditions")
int sensorOrientation = mCameraCharacteristics.get(
CameraCharacteristics.SENSOR_ORIENTATION);
mPreviewRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,
(sensorOrientation +
mDisplayOrientation * (mFacing == Constants.FACING_FRONT ? 1 : -1) +
360) % 360);
// Stop preview and capture a still picture.
mCaptureSession.stopRepeating();
mCaptureSession.capture(mPreviewRequestBuilder.build(),
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
mPreviewRequestBuilder.removeTarget(mImageReader.getSurface());
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_PREVIEW);
try {
mCaptureSession.capture(mPreviewRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
// unlockFocus();
}
}, null);
} catch (CameraAccessException e) {
Log.e(TAG, "Cannot capture a still picture.", e);
}
}
网友评论