Camera2 高级特性:曝光控制、对焦模式、白平衡、HDR、人脸检测

各位同学,今天我们来聊聊 Camera2 里那些真正决定画面质量的高级特性。说实话,很多开发者用 Camera2 只是停留在打开预览、拍照这个层面,但真正让 App 脱颖而出的,恰恰是这些细节控制。

我个人习惯把 Camera2 的高级特性分成两类:一类是「基础画质控制」,比如曝光、对焦、白平衡;另一类是「智能增强功能」,比如 HDR 和人脸检测。咱们一个一个来拆解。

曝光控制:让画面亮暗恰到好处

曝光控制说白了就是控制进光量。Camera2 提供了三种曝光模式:

  • AE_MODE_ON:自动曝光,系统帮你算
  • AE_MODE_OFF:完全手动,你自己控制
  • AE_MODE_ON_AUTO_FLASH:自动曝光 + 自动闪光灯

我在项目中遇到过一个问题:在光线复杂的场景下,自动曝光经常过曝或欠曝。后来发现,其实我们可以通过 CONTROL_AE_EXPOSURE_COMPENSATION 来做曝光补偿。

核心思路:曝光补偿的范围一般是 -12 到 +12,步长由 AE_COMPENSATION_STEP 决定。每步通常对应 1/3 EV。

// 设置曝光补偿 +2 档
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
int step = characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP).toInt();
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 2 * step);

嗯,这里要注意:不是所有设备都支持曝光补偿。你得先检查一下 CONTROL_AE_COMPENSATION_RANGE

对焦模式:从自动到手动的进阶之路

对焦模式这块,我建议你记住三个最常用的:

模式适用场景我的经验
CONTROL_AF_MODE_AUTO普通拍照适合大多数场景,但速度一般
CONTROL_AF_MODE_CONTINUOUS_PICTURE视频录制持续追焦,我拍视频时必用
CONTROL_AF_MODE_MACRO微距拍摄拍文档、小物件时效果拔群

我曾经踩过一个坑:在低光环境下用 CONTINUOUS_PICTURE 模式,结果对焦一直在来回拉风箱。后来发现,低光下应该先切换到 AUTO 模式,等对焦完成后再锁定。

小技巧:手动对焦时,可以用 LENS_FOCUS_DISTANCE 来设置。值越小,对焦越近。0 表示无穷远。

// 手动对焦到最近距离
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 0.0f);

白平衡:还原真实色彩的关键

白平衡这东西,说白了就是告诉相机「什么是白色」。Camera2 提供了几个预设模式:

  • CONTROL_AWB_MODE_AUTO:自动白平衡,大多数情况够用
  • CONTROL_AWB_MODE_DAYLIGHT:日光模式,约 5200K
  • CONTROL_AWB_MODE_FLUORESCENT:荧光灯模式,约 4000K
  • CONTROL_AWB_MODE_INCANDESCENT:白炽灯模式,约 2800K

你想想看,为什么有时候在室内拍出来的照片偏黄?其实就是白平衡没调对。我个人的习惯是:在混合光源环境下,直接用手动白平衡。

// 手动设置色温 4500K
builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
builder.set(CaptureRequest.COLOR_CORRECTION_MODE, CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
builder.set(CaptureRequest.COLOR_CORRECTION_GAINS, new RggbChannelVector(1.2f, 1.0f, 1.0f, 1.0f));

注意:手动设置白平衡时,需要同时关闭自动白平衡模式。否则系统会覆盖你的设置。

HDR:高动态范围的正确打开方式

HDR 的原理其实很简单:拍多张不同曝光的照片,然后合成一张。Camera2 里通过 CONTROL_ENABLE_ZSLCONTROL_MODE 来控制。

我记得第一次在 Camera2 里实现 HDR 时,遇到了一个坑:有些设备不支持 HDR 模式。所以一定要先检查:

int[] availableModes = characteristics.get(
    CameraCharacteristics.CONTROL_AVAILABLE_MODES);
boolean supportsHdr = false;
for (int mode : availableModes) {
    if (mode == CaptureRequest.CONTROL_MODE_USE_SCENE_MODE) {
        supportsHdr = true;
        break;
    }
}

启用 HDR 的代码其实不复杂:

builder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
builder.set(CaptureRequest.CONTROL_SCENE_MODE, CaptureRequest.CONTROL_SCENE_MODE_HDR);

避坑指南:我曾经在预览时启用 HDR,结果帧率直接掉到 15fps。后来发现,HDR 模式下预览帧率会下降,建议只在拍照时启用。

人脸检测:让相机更智能

人脸检测是 Camera2 里一个很实用的特性。它可以让相机自动对人脸区域进行曝光和对焦优化。

启用方式很简单:

// 检查是否支持人脸检测
int maxFaces = characteristics.get(
    CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);
if (maxFaces > 0) {
    builder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
        CaptureRequest.STATISTICS_FACE_DETECT_MODE_SIMPLE);
}

检测到人脸后,你可以通过 CaptureResult 获取人脸信息:

Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
if (faces != null) {
    for (Face face : faces) {
        Rect bounds = face.getBounds();
        int score = face.getScore();
        // 根据人脸位置调整曝光
    }
}

我个人觉得,人脸检测最实用的场景是:在多人合影时,自动调整曝光让所有人脸都清晰。嗯,这个功能在视频通话 App 里特别有用。

知识体系总览

下面这张图是我整理的 Camera2 高级特性关系图,你看一眼就能明白各个模块之间的关联:

Camera2 高级特性 曝光控制 AE_MODE_ON 曝光补偿 对焦模式 AUTO / CONTINUOUS 手动对焦距离 白平衡 AWB_MODE 手动色温 HDR SCENE_MODE_HDR 多帧合成 人脸检测 FACE_DETECT_MODE 人脸区域曝光优化 五大核心特性关系图

从这张图你可以看到,五个特性虽然独立,但最终都服务于同一个目标:让画面更清晰、色彩更真实、曝光更准确。

我的建议:在实际项目中,不要一次性把所有特性都打开。先保证基础预览流畅,再逐步添加高级功能。我曾经在一个项目里同时开了 HDR 和人脸检测,结果手机发热严重,帧率惨不忍睹。

好了,关于 Camera2 的高级特性就讲到这里。这些功能用好了,你的 App 在画质上就能甩开竞争对手一大截。记住,技术是为产品服务的,不要为了炫技而滥用特性。


公众号:蓝海资料掘金营,微信deep3321