美文网首页
Android Camera2 相机拍照

Android Camera2 相机拍照

作者: svvvvvvvL | 来源:发表于2019-10-23 10:33 被阅读0次

    实现特点

    • 不需要自动对焦
    • 正常触发闪光灯flash
    • 复用CaptureRequest.Builder, 参数完全一致

    流程

    1. 按照常规方式打开预览
    2. 设置好相应的全局变量:
      • CameraDevicemCamera
      • CameraCaptureSessionmCaptureSession
      • CaptureRequest.BuildermPreviewRequestBuilder
      • ImageReadermImageReader
    3. 定义一个类似takePicture()的开始拍照方法
    4. 不用对焦, 直接开始拍照, 调用类似captureStillPicture()的方法
    5. 拍摄前, 如果需要闪光的, 需要设置
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
    

    这条语句会触发闪光的开启动作

    1. 添加拍摄图片的输出
    mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
    
    1. 设置当前的拍摄意图
    mPreviewRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
    

    这条设置页会影响到闪光的正常开启. 如果不需要闪光灯的话, 设置了也没事.

    1. 设置图片的方向
      因为物理相机的镜头方向可能和手机的朝向不一致(手机倒着拿), 所以设置这个是确保拍摄出来的图片永远是正向的
      int sensorOrientation = mCameraCharacteristics.get(
                        CameraCharacteristics.SENSOR_ORIENTATION);
                mPreviewRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION,
                        (sensorOrientation +
                                mDisplayOrientation * (mFacing == Constants.FACING_FRONT ? 1 : -1) +
                                360) % 360);
    
    1. 停止画面预览
    mCaptureSession.stopRepeating();
    

    也可以不调用这条, 不停止画面. 不过这样会出现闪光灯闪烁2次的问题.

    1. 开始拍照
       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);
    
    1. 结束了.

    完整部分代码

        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);
            }
        }
    

    相关文章

      网友评论

          本文标题:Android Camera2 相机拍照

          本文链接:https://www.haomeiwen.com/subject/nhkcvctx.html