3、Android Camera2 API概览:CameraManager、CameraDevice、CaptureRequest、CaptureSession核心组件
Android Camera2 API 是 Android 5.0(API 21)引入的相机框架,取代了已废弃的 Camera1 API。它为开发者提供了对相机设备的精细控制,是实现多帧融合、HDR 处理等高级算法的基石。本章将深入剖析 Camera2 的四大核心组件:CameraManager、CameraDevice、CaptureRequest 和 CaptureSession,并阐述它们如何协同工作以完成一次高质量的图像捕获。
3.1 CameraManager:相机系统的入口
CameraManager 是系统服务的客户端代理,负责枚举和管理所有可用的相机设备。它是整个 Camera2 操作的起点。
3.1.1 主要职责
- 枚举相机:通过
getCameraIdList()获取所有可用相机的 ID 列表。 - 查询特性:通过
getCameraCharacteristics(cameraId)获取指定相机的详细能力参数,如传感器尺寸、像素大小、支持的 AE/AWB 模式、HDR 支持级别等。 - 打开相机:通过
openCamera(cameraId, stateCallback, handler)异步打开指定相机设备。
3.1.2 关键方法
| 方法 | 描述 | 返回值/回调 |
|---|---|---|
getCameraIdList() |
获取所有可用相机 ID 的数组 | String[] |
getCameraCharacteristics(String cameraId) |
获取指定相机的静态特性信息 | CameraCharacteristics |
openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler) |
异步打开相机设备 | 通过 CameraDevice.StateCallback 回调 |
CameraCharacteristics 检查 INFO_SUPPORTED_HARDWARE_LEVEL,以确认设备是 FULL 或 LEVEL_3 级别,这些级别才支持多帧融合所需的同步帧和高速连拍能力。
3.1.3 CameraCharacteristics 关键查询项
SCALER_STREAM_CONFIGURATION_MAP:获取支持的输出尺寸和格式。SENSOR_INFO_SENSITIVITY_RANGE:ISO 感光度范围。CONTROL_AE_AVAILABLE_MODES:自动曝光支持的模式(如 ON、OFF、ON_AUTO_FLASH)。STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES:人脸检测支持级别。
3.2 CameraDevice:相机硬件抽象
CameraDevice 代表一个物理或逻辑相机设备。一旦通过 CameraManager.openCamera() 成功打开,应用程序便获得了一个 CameraDevice 实例,用于创建捕获会话和请求。
3.2.1 状态回调
打开相机时需传入 CameraDevice.StateCallback,其回调方法包括:
onOpened(CameraDevice camera):相机成功打开,可以开始创建会话。onDisconnected(CameraDevice camera):相机连接断开(如被其他应用抢占)。onError(CameraDevice camera, int error):相机发生错误,需要释放资源。
3.2.2 核心方法
| 方法 | 描述 |
|---|---|
createCaptureRequest(int templateType) |
根据模板类型(如 TEMPLATE_PREVIEW、TEMPLATE_STILL_CAPTURE)创建 CaptureRequest.Builder |
createCaptureSession(SessionConfiguration config) |
创建捕获会话,配置输入/输出 Surface |
close() |
关闭相机设备,释放资源 |
close() 释放。建议在 onPause() 或 onDestroy() 中执行关闭操作,避免内存泄漏。
3.3 CaptureRequest:捕获参数配置
CaptureRequest 定义了单次图像捕获的所有参数,包括曝光、对焦、白平衡、输出目标等。它由 CaptureRequest.Builder 构建,是不可变对象。
3.3.1 模板类型
createCaptureRequest(int templateType) 支持以下预定义模板:
| 模板常量 | 适用场景 |
|---|---|
TEMPLATE_PREVIEW |
取景预览,优化帧率和功耗 |
TEMPLATE_STILL_CAPTURE |
静态照片捕获,优先画质 |
TEMPLATE_VIDEO_SNAPSHOT |
视频录制中的快照 |
TEMPLATE_ZERO_SHUTTER_LAG |
零快门延迟模式(需硬件支持) |
TEMPLATE_MANUAL |
完全手动控制,不应用任何自动算法 |
3.3.2 关键参数设置
// 创建 CaptureRequest.Builder
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 设置曝光补偿
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
// 设置 ISO 和曝光时间(手动模式)
builder.set(CaptureRequest.SENSOR_SENSITIVITY, 200);
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 10000000L); // 10ms
// 设置对焦模式
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 添加输出目标 Surface
builder.addTarget(surface);
// 构建不可变的 CaptureRequest
CaptureRequest request = builder.build();
3.3.3 多帧融合中的关键参数
- 曝光时间(SENSOR_EXPOSURE_TIME):控制每帧的曝光时长,HDR 多帧融合通常需要不同曝光时间的帧序列。
- 感光度(SENSOR_SENSITIVITY):ISO 值,影响图像亮度和噪声水平。
- 帧持续时间(SENSOR_FRAME_DURATION):控制帧间隔,影响连拍速度。
- AE 模式(CONTROL_AE_MODE):设置为 OFF 以手动控制曝光参数。
3.4 CaptureSession:捕获会话管理
CaptureSession 是 Camera2 管道中的核心执行单元。它负责接收 CaptureRequest,驱动 CameraDevice 输出图像数据到指定的 Surface。一个 CameraDevice 一次只能有一个活跃的 CaptureSession。
3.4.1 创建会话
通过 CameraDevice.createCaptureSession(SessionConfiguration config) 创建。SessionConfiguration 包含:
- 输出配置(OutputConfiguration):定义输出 Surface 及其格式、尺寸。
- 会话回调(CameraCaptureSession.StateCallback):监听会话状态变化。
- 执行器(Executor):回调执行的线程池。
3.4.2 捕获模式
| 方法 | 描述 | 适用场景 |
|---|---|---|
capture(CaptureRequest request, CaptureCallback callback, Handler handler) |
单次捕获,返回一帧图像 | 普通拍照 |
captureBurst(List<CaptureRequest> requests, CaptureCallback callback, Handler handler) |
批量捕获,按顺序返回多帧图像 | 多帧融合、HDR 连拍 |
setRepeatingRequest(CaptureRequest request, CaptureCallback callback, Handler handler) |
持续重复捕获,用于预览 | 取景器预览 |
setRepeatingBurst(List<CaptureRequest> requests, CaptureCallback callback, Handler handler) |
持续重复批量捕获 | 高速连拍、视频录制 |
3.4.3 CaptureCallback 关键回调
onCaptureStarted(CaptureSession session, CaptureRequest request, long timestamp, long frameNumber):捕获开始,可用于同步 UI。onCaptureProgressed(CaptureSession session, CaptureRequest request, CaptureResult partialResult):部分结果可用(如 AE 状态)。onCaptureCompleted(CaptureSession session, CaptureRequest request, TotalCaptureResult result):捕获完成,包含完整的元数据。onCaptureFailed(CaptureSession session, CaptureRequest request, CaptureFailure failure):捕获失败,需处理错误。
captureBurst() 发送一组不同曝光参数的 CaptureRequest,在 onCaptureCompleted() 中收集所有帧的 TotalCaptureResult 和 Image,然后传递给融合算法。注意帧顺序与请求顺序一致。
3.5 组件协作流程示例
以下代码片段展示了四大组件如何协同完成一次 HDR 多帧捕获:
// 1. 获取 CameraManager
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
// 2. 打开相机
manager.openCamera(cameraId, new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
// 3. 创建 CaptureRequest.Builder(使用手动模板)
CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
builder.addTarget(outputSurface);
// 4. 构建多帧请求列表(不同曝光)
List<CaptureRequest> requestList = new ArrayList<>();
for (int exp : new int[]{-3, 0, 3}) {
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, expTimeBase * (long) Math.pow(2, exp));
requestList.add(builder.build());
}
// 5. 创建 CaptureSession
camera.createCaptureSession(new SessionConfiguration(
SessionConfiguration.SESSION_REGULAR,
Arrays.asList(new OutputConfiguration(outputSurface)),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
// 6. 发送 burst 请求
session.captureBurst(requestList, new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
// 7. 收集帧数据,传递给融合算法
processFrame(result);
}
}, backgroundHandler);
}
}, backgroundHandler
));
}
}, backgroundHandler);
onCaptureFailed() 中打印 CaptureFailure.getReason(),常见原因包括:帧超时、Surface 已释放、硬件资源不足。这些信息对定位问题至关重要。
3.6 本章小结
- CameraManager 是系统入口,负责枚举和打开相机设备。
- CameraDevice 代表相机硬件,提供创建请求和会话的方法。
- CaptureRequest 封装了每次捕获的参数,支持手动控制曝光、ISO 等关键参数。
- CaptureSession 是执行引擎,通过
captureBurst()实现多帧序列捕获,是多帧融合的核心机制。 - 四大组件通过异步回调协作,开发者需正确处理状态转换和错误恢复。