2. Android Camera2 框架基础:核心组件详解

在实现 HDR 多帧融合之前,必须深入理解 Camera2 框架的四大核心组件:CameraManager、CameraDevice、CaptureSession 和 CaptureRequest。它们构成了从设备发现、打开、会话建立到单次捕获请求的完整链路。HDR 的多帧曝光序列正是通过精确控制这些组件的协作来完成的。

2.1 组件全景与职责划分

下表总结了四个核心组件在 Camera2 框架中的角色与关键职责:

组件 角色 关键职责 HDR 相关要点
CameraManager 系统级相机管理器 枚举相机、获取特性、打开相机 查询是否支持 HDR 模式、获取传感器能力
CameraDevice 相机设备代理 创建捕获会话、配置输出流 创建支持多帧输出的会话
CaptureSession 捕获会话 管理捕获请求队列、回调结果 发送多帧 HDR 请求序列、接收融合帧
CaptureRequest 单次捕获指令 定义曝光、增益、对焦等参数 设置不同曝光值(EV)的请求序列
关键理解:Camera2 框架采用管道(Pipeline)架构。CaptureRequest 是输入,经过 CameraDevice 内部的 ISP 管道处理,最终通过 CaptureSession 的回调输出结果。HDR 多帧融合正是利用这一管道,在短时间内注入多组不同曝光的 CaptureRequest。

2.2 CameraManager:相机系统的入口

CameraManager 是应用与相机硬件之间的第一个接触点。它负责系统级相机设备的发现与特性查询。

  • 获取实例:通过 context.getSystemService(Context.CAMERA_SERVICE) 获得。
  • 枚举相机:getCameraIdList() 返回所有可用相机 ID。
  • 查询特性:getCameraCharacteristics(cameraId) 返回 CameraCharacteristics 对象,包含传感器尺寸、像素大小、AE 补偿范围、是否支持 HDR 等关键信息。
  • 打开相机:openCamera(cameraId, stateCallback, handler) 异步打开指定相机。
// 获取 CameraManager 实例
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);

// 查询相机特性,判断是否支持 HDR
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
int[] availableModes = characteristics.get(
    CameraCharacteristics.CONTROL_AVAILABLE_MODES);
boolean supportsHdr = false;
for (int mode : availableModes) {
    if (mode == CameraMetadata.CONTROL_MODE_USE_SCENE_MODE) {
        // 进一步检查场景模式是否包含 HDR
        int[] sceneModes = characteristics.get(
            CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES);
        for (int scene : sceneModes) {
            if (scene == CameraMetadata.CONTROL_SCENE_MODE_HDR) {
                supportsHdr = true;
                break;
            }
        }
    }
}
实践提示:在 HDR 实现中,CameraManager 主要用于在初始化阶段确认设备能力。如果设备不支持 HDR 场景模式,可以考虑使用手动曝光补偿(AE Compensation)实现多帧融合。

2.3 CameraDevice:相机硬件抽象

CameraDevice 代表一个打开的相机设备。它是创建捕获会话和配置输出流的唯一入口。

  • 状态回调:CameraDevice.StateCallback 监听设备打开、断开、错误等状态。
  • 创建会话:createCaptureSession(sessionConfig, callback, handler) 创建捕获会话。
  • 输出配置:通过 SessionConfiguration 或 createCaptureRequest 配置输出 Surface(如 TextureView、ImageReader)。
// 打开相机
manager.openCamera(cameraId, new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice camera) {
        // 保存 CameraDevice 实例
        cameraDevice = camera;
        // 创建捕获会话
        createCaptureSession();
    }

    @Override
    public void onDisconnected(@NonNull CameraDevice camera) {
        camera.close();
    }

    @Override
    public void onError(@NonNull CameraDevice camera, int error) {
        camera.close();
    }
}, backgroundHandler);
注意:CameraDevice 是重量级资源。在 HDR 多帧捕获过程中,必须确保在 Activity/Fragment 生命周期中正确打开和关闭,避免资源泄漏。建议在 onPause() 中关闭设备。

2.4 CaptureSession:捕获会话与管道管理

CaptureSession 是 Camera2 框架中最核心的运行时组件。它管理着从应用发送 CaptureRequest 到硬件处理并返回结果的全过程。

  • 请求提交:capture(request, callback, handler) 提交单次捕获;setRepeatingRequest(request, callback, handler) 提交重复捕获。
  • 结果回调:CameraCaptureSession.CaptureCallback 提供 onCaptureStarted、onCaptureProgressed、onCaptureCompleted 等回调。
  • 会话关闭:close() 释放会话资源。
// 创建捕获会话
List<Surface> outputSurfaces = Arrays.asList(imageReader.getSurface(), textureView.getSurface());
cameraDevice.createCaptureSession(outputSurfaces, 
    new CameraCaptureSession.StateCallback() {
        @Override
        public void onConfigured(@NonNull CameraCaptureSession session) {
            captureSession = session;
            // 会话就绪,可以发送请求
            startHdrCapture();
        }

        @Override
        public void onConfigureFailed(@NonNull CameraCaptureSession session) {
            // 处理配置失败
        }
    }, backgroundHandler);
HDR 关键点:CaptureSession 支持同时提交多个 CaptureRequest。在 HDR 多帧融合中,我们通常连续提交 3 个请求(欠曝、正常、过曝),每个请求的曝光补偿不同。会话会按顺序处理这些请求,并通过回调返回每一帧的原始数据。

2.5 CaptureRequest:精确控制每一帧

CaptureRequest 是 Camera2 框架中粒度最小的控制单元。它定义了单次捕获所需的所有参数,包括曝光、对焦、白平衡、输出目标等。

  • 创建:通过 cameraDevice.createCaptureRequest(templateType) 创建,模板类型包括 TEMPLATE_PREVIEW、TEMPLATE_STILL_CAPTURE、TEMPLATE_MANUAL 等。
  • 参数设置:通过 builder.set(key, value) 设置各种控制参数。
  • 输出目标:通过 builder.addTarget(surface) 指定输出 Surface。
  • 构建:builder.build() 生成不可变的 CaptureRequest 对象。
// 创建 HDR 多帧请求序列
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(
    CameraDevice.TEMPLATE_STILL_CAPTURE);

// 设置输出目标
builder.addTarget(imageReader.getSurface());

// 创建三个不同曝光的请求
// 欠曝帧:-2 EV
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, -6);
CaptureRequest underexposed = builder.build();

// 正常帧:0 EV
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
CaptureRequest normal = builder.build();

// 过曝帧:+2 EV
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 6);
CaptureRequest overexposed = builder.build();

// 依次提交三个请求
captureSession.capture(underexposed, captureCallback, backgroundHandler);
captureSession.capture(normal, captureCallback, backgroundHandler);
captureSession.capture(overexposed, captureCallback, backgroundHandler);
曝光补偿单位:曝光补偿值(EV)的单位是 1/3 EV step。因此 -6 表示 -2 EV,+6 表示 +2 EV。不同设备的步长可能不同,建议通过 CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP 查询实际步长。

2.6 核心组件协作流程(SVG 架构图)

下图展示了 Camera2 框架四大核心组件在 HDR 多帧捕获场景下的完整协作流程:

Camera2 核心组件协作流程 - HDR 多帧捕获 Camera2 核心组件协作流程(HDR 多帧捕获) CameraManager openCamera() CameraDevice createCaptureSession() CaptureSession capture() × 3 Request 1: -2 EV Request 2: 0 EV Request 3: +2 EV Frame 1: 欠曝 Frame 2: 正常 Frame 3: 过曝 HDR 融合输出帧 HDR 多帧融合:3 帧 → 1 帧 通过 CaptureSession 连续提交

2.7 组件生命周期与 HDR 调度时序

在 HDR 多帧捕获中,组件的生命周期管理直接影响融合质量。以下是推荐的调度时序:

  1. 初始化阶段:通过 CameraManager 查询设备能力,确认支持 HDR 或手动曝光补偿。
  2. 打开设备:异步打开 CameraDevice,在 onOpened 回调中创建 CaptureSession。
  3. 会话就绪:在 onConfigured 回调中构建 HDR 请求序列。
  4. 捕获阶段:连续提交 3 个不同曝光的 CaptureRequest,确保帧间间隔最小化。
  5. 结果处理:在 onCaptureCompleted 回调中收集每一帧的 Image 数据。
  6. 融合输出:所有帧就绪后,执行多帧融合算法生成 HDR 结果。
  7. 资源释放:关闭 CaptureSession 和 CameraDevice。
时序关键点:HDR 多帧捕获要求三帧之间的时间差尽可能小,以避免场景运动导致的重影(Ghosting)问题。建议在提交请求时使用 capture() 而非 setRepeatingRequest(),并确保三个请求在同一个消息循环中连续提交。

2.8 核心组件 API 速查表

组件 关键方法/回调 HDR 使用场景
CameraManager getCameraCharacteristics() 查询 AE 补偿范围、HDR 场景模式支持
CameraDevice createCaptureSession() 创建支持多帧输出的会话
CaptureSession capture() 提交 HDR 多帧请求序列
CaptureRequest CONTROL_AE_EXPOSURE_COMPENSATION 设置不同 EV 值生成多帧
CaptureCallback onCaptureCompleted() 接收每一帧的元数据和图像数据
总结:Camera2 框架的四大核心组件构成了一个从系统管理到硬件控制的完整链路。在 HDR 多帧融合实现中,CameraManager 负责能力探测,CameraDevice 负责设备管理,CaptureSession 负责请求调度,CaptureRequest 负责精确控制每一帧的曝光参数。理解这四者的协作关系,是后续实现多帧融合算法的基础。