Camera2 采集

2022-10-25 16:34:31 浏览数 (1)

本篇介绍

Camera2相比Camera1,使用起来要复杂一些,不过也节省了一些逻辑,比如可以自动处理角度问题。本篇就按照流程介绍下Camera2的简单使用,更多细节会后续介绍。

使用Camera2

  1. 申请权限 静态申请:
代码语言:javascript复制
<uses-permission android:name="android.permission.CAMERA" />

动态申请:

代码语言:javascript复制
 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            return;
        }
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
  1. 获取目标Camera
代码语言:javascript复制
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            String[] ids = manager.getCameraIdList();
            for (String id : ids) {
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
                if (characteristics == null) {
                    continue;
                }
                if (characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
                    mCameraId = id;
                    break;
                }
            }

            if (mCameraId == null) {
                return;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
  1. 打开Camera:
代码语言:javascript复制
 if (mCameraId == null) {
            return;
        }
        CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                return;
            }
            manager.openCamera(mCameraId, new StateCallback() {
                @Override
                public void onOpened(@NonNull CameraDevice camera) {
                    mCameraOpenCloseLock.release();
                    mCamera = camera;
                    createCameraPreviewSession();
                }

                @Override
                public void onDisconnected(@NonNull CameraDevice camera) {
                    mCameraOpenCloseLock.release();
                    camera.close();
                    mCamera = null;
                }

                @Override
                public void onError(@NonNull CameraDevice camera, int error) {
                    mCameraOpenCloseLock.release();
                    camera.close();
                    mCamera = null;
                }}, handler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

这儿可以看到打开Camera是一个异步操作,因此添加了一个信号量mCameraOpenCloseLock,用来间接让操作变成同步。这样就可以避免打开Camera还没完成,就关闭Camera时出现的不可预料的问题。 在Camera打开的回调中,就可以发送预览请求了。

  1. 请求预览
代码语言:javascript复制
 private void createCameraPreviewSession() {
        try {
            mCaptureRequestBuilder = mCamera.createCaptureRequest(TEMPLATE_PREVIEW);
            mCaptureRequestBuilder.addTarget(mSurfaceView.getHolder().getSurface());

            mCamera.createCaptureSession(Arrays.asList(mSurfaceView.getHolder().getSurface()),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                            mCaptureSession = cameraCaptureSession;
                            if (mCaptureSession != null) {
                                try {
                                    mCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), null, null); // 连续请求
                                } catch (CameraAccessException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                        @Override
                        public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {

                        }
                    }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
  1. 关闭Camera:
代码语言:javascript复制
 try {
            mCameraOpenCloseLock.acquire();
            mCaptureSession.stopRepeating();
            mCamera.close();
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            mCameraOpenCloseLock.release();
        }

完整代码地址

0 人点赞