Android Camera2 之 CameraDevice 详解

一、简介

CameraDevice 是一个连接的相机设备代表,你可以把它看作为相机设备在 java 代码中的表现。类比于旧 API 中的 Camera 类。

官方文档链接:https://developer.android.google.cn/reference/android/hardware/camera2/CameraDevice

二、获取 CameraDevice 实例

通过 CameraManageropenCamera() 方法打开相机,在 CameraDevice.StateCallbackonOpened(CameraDevice camera) 方法中可获得 CameraDevice 的实例。

示例:

    private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT;
    private CameraManager mCameraManager; // 相机管理者
    private CameraDevice mCameraDevice; // 相机对象
    private Handler mBackgroundHandler;
    private HandlerThread mBackgroundThread;

    private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            mCameraDevice = camera; // 获取到可用的 CameraDevice 实例
            // 当相机成功打开时回调该方法,接下来可以执行创建预览的操作
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            // 当相机断开连接时回调该方法,应该在此执行释放相机的操作
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            // 当相机打开失败时,应该在此执行释放相机的操作
        }

        @Override
        public void onClosed(@NonNull CameraDevice camera) {
            // 当相机关闭时回调该方法,这个方法可以不用实现
        }
    };

    public void openCamera() {
        try {
            // 前处理
            mCameraManager.openCamera(Integer.toString(mCameraId), mStateCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

三、内部类

只有一个 CameraDevice.StateCallback 的内部类,当相机状态发生变化时,会调用该类相应的回调方法。

相应的回调方法介绍在上面的示例中已经说明了,下面介绍一下 onError 回调方法中相应的错误码把:

错误码 描述
CameraDevice.StateCallback.ERROR_CAMERA_IN_USE 当前相机设备已经在一个更高优先级的地方打开了
CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE 已打开相机数量到上限了,无法再打开新的相机了
CameraDevice.StateCallback.ERROR_CAMERA_DISABLED 由于相关设备策略该相机设备无法打开,详细可见 DevicePolicyManagersetCameraDisabled(ComponentName, boolean) 方法
CameraDevice.StateCallback.ERROR_CAMERA_DEVICE 相机设备发生了一个致命错误
CameraDevice.StateCallback.ERROR_CAMERA_SERVICE 相机服务发生了一个致命错误

四、常用方法

1. void close()

关闭对应的相机设备。

2. CaptureRequest.Builder createCaptureRequest(int templateType)

使用指定模板创建一个 CaptureRequest.Builder 用于新的捕获请求构建。

templateType 描述 适用性
TEMPLATE_PREVIEW 用于创建一个相机预览请求。相机会优先保证高帧率而不是高画质 所有相机设备
TEMPLATE_STILL_CAPTURE 用于创建一个拍照请求。相机会优先保证高画质而不是高帧率 所有相机设备
TEMPLATE_RECORD 用于创建一个录像请求。相机会使用标准帧率,并设置录像级别的画质 所有相机设备
TEMPLATE_VIDEO_SNAPSHOT 用于创建一个录像时拍照的请求。相机会尽可能的保证照片质量的同时不破坏正在录制的视频质量 硬件支持级别高于 LEGACY 的相机设备
TEMPLATE_ZERO_SHUTTER_LAG 用于创建一个零延迟拍照的请求。相机会尽可能的保证照片质量的同时不损失预览图像的帧率,3A(自动曝光、自动聚焦、自动白平衡)都为 auto 模式 支持 PRIVATE_REPROCESSINGYUV_REPROCESSING 的相机设备
TEMPLATE_MANUAL 用于创建一个手动控制相机参数的请求。相机所有自动控制将被禁用,后期处理参数为预览质量,手动控制参数被设置为合适的默认值,需要用户自己根据需求来调整各参数 支持 MANUAL_SENSOR 的相机设备

3. void createCaptureSession(List outputs, CameraCaptureSession.StateCallback callback, Handler handler)

使用一个指定的 Surface 输出列表创建一个相机捕捉会话。

参数说明:

  • outputs : 输出的 Surface 集合,每个 CaptureRequest 的输出 Surface 都应该是 outputs 的一个子元素。
  • callback : 创建会话的回调。成功时将调用 CameraCaptureSession.StateCallback 的 onConfigured(CameraCaptureSession session) 方法。
  • handler : 指定回调执行的线程,传 null 时默认使用当前线程的 Looper。

4. String getId()

获得当前相机设备的 id。

5. 示例

针对第二条和第三条,简单的使用如下:

try {
    // templateType 使用 TEMPLATE_PREVIEW,即创建一个相机预览请求
    mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
    mCaptureRequestBuilder.addTarget(mPreviewSurface); // 设置预览输出的 Surface
    // mPreviewSurface 是用于预览输出的 Surface
    // mImageReader.getSurface() 是用于拍照输出的 Surface
    mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()),
            new CameraCaptureSession.StateCallback() {

        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            if (mCameraDevice == null) {
                return;
            }
            mCaptureSession = session;
            try {
                // 设置连续自动对焦
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                // 设置关闭闪光灯
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.FLASH_MODE_OFF);
                // 生成一个预览的请求
                mPreviewRequest = mPreviewRequestBuilder.build();
                // 开始预览,即设置反复请求
                mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            Log.e(TAG, "ConfigureFailed.");
        }
    }, mBackgroundHandler);
} catch (CameraAccessException e) {
    e.printStackTrace();
}

五、硬件支持等级

上面介绍适用性时提到了硬件支持级别。在 Camera2 中,相机设备支持的硬件等级有

LEVEL_3 > FULL > LIMIT > LEGACY

对于大多数的手机而言,都会支持到 FULLLIMIT。当支持到 FULL 等级的相机设备,将拥有比旧 API 强大的新特性,如 30fps 全高清连拍,帧之间的手动设置,RAW 格式的图片拍摄,快门零延迟以及视频速拍等,否则和旧 API 功能差别不大。

获取方式:

通过 CameraCharacteristics 类获取相机设备的特性,包括硬件等级的支持等级.

CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(mCameraId);
int hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);

你可能感兴趣的:(Android)