實現特點
- 實現自動對焦
- 選擇性正常觸發閃光燈flash
- 複用CaptureRequest.Builder, 參數完全一致
- 拍照注意事項講解
- 代碼片段詳解
流程
- 按照常規方式打開預覽
- 設置好相應的全局變量:
CameraDevice的cameraDevice
CameraCaptureSession的mPreviewSession
CaptureRequest.Builder的captureRequestBuilder
ImageReader的imageReader
等 - 定義一個類似takePicture()的開始拍照方法
- 自動對焦 對焦, 直接開始拍照, 調用類似captureStillPicture()的方法
- 自動對焦
// 設置自動對焦模式
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
- 拍攝前, 如果需要閃光的, 需要設置
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
上面這條語句會觸發閃光的開啓動作
- 添加拍攝圖片的輸出
captureRequestBuilder.addTarget(mImageReader.getSurface());
- 設置當前的拍攝意圖
captureRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
這條設置頁會影響到閃光的正常開啓. 如果不需要閃光燈的話, 設置了也沒事.
- 設置圖片的方向
因爲物理相機的鏡頭方向可能和手機的朝向不一致(手機倒着拿), 所以設置這個是確保拍攝出來的圖片永遠是正向的
int sensorOrientation = mCameraCharacteristics.get(
CameraCharacteristics.SENSOR_ORIENTATION);
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,
(sensorOrientation +
mDisplayOrientation * (mFacing == Constants.FACING_FRONT ? 1 : -1) +
360) % 360);
- 停止畫面預覽
mPreviewSession.stopRepeating();
也可以不調用這條, 不停止畫面. 不過這樣會出現閃光燈閃爍2次的問題.
- 開始拍照
mPreviewSession.capture(captureRequestBuilder.build(),
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
//移除輸出到ImageReader, 不移除的話,會造成拍照停不下來的問題
captureRequestBuilder.removeTarget(imageReader.getSurface());
//恢復相機預提爲預覽
captureRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_PREVIEW);
try {
//不加這句話, 閃光燈無法正常工作, 如果不適用閃光等, 可以不加
mPreviewSession.capture(mPreviewRequestBuilder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}, null);
- 完整部分代碼
/**拍照*/
private void takePicture()
{
try
{
if (cameraDevice == null)
{
return;
}
// 創建拍照請求
captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 設置自動對焦模式
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
// 將imageReader的surface設爲目標
captureRequestBuilder.addTarget(imageReader.getSurface());
// 獲取設備方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
// 根據設備方向計算設置照片的方向
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION
, ORIENTATIONS.get(rotation));
mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 5);
// 停止連續取景
mPreviewSession.stopRepeating();
mPreviewSession.abortCaptures();
//拍照
CaptureRequest captureRequest = captureRequestBuilder.build();
//設置拍照監聽
mPreviewSession.capture(captureRequest,captureCallback, null);
}
catch (CameraAccessException e)
{
e.printStackTrace();
}
}