13. Camera 曝光控制:AE模式详解、AE补偿、AE锁定、手动曝光时间设置、ISO设置与增益控制

曝光控制,说白了就是决定照片亮度的核心机制。我做了这么多年相机开发,发现很多开发者对AE的理解停留在“自动挡”层面,一旦遇到复杂场景就抓瞎。今天咱们就把曝光控制这块彻底掰开揉碎。

13.1 AE模式详解:你到底想要哪种自动?

Android Camera2 提供了三种AE模式,我习惯把它们比作开车:

  • AE_MODE_ON:全自动模式。相机自己决定曝光时间和ISO。适合日常随手拍。
  • AE_MODE_ON_AUTO_FLASH:自动模式+闪光灯辅助。光线不足时自动闪。
  • AE_MODE_ON_EXTERNAL_FLASH:外接闪光灯模式。专业场景用的多。

嗯,这里要注意:AE_MODE_OFF 并不是一个独立的模式,而是通过 CONTROL_AE_MODE 设置为 AE_MODE_OFF 并配合手动曝光参数来实现的。说白了,关掉AE就是完全手动。

核心要点:AE模式的选择决定了曝光策略。我个人习惯在预览阶段用 AE_MODE_ON,拍照时根据场景动态切换。

13.2 AE补偿:微调曝光的艺术

AE补偿是什么?就是告诉相机:“你算出来的曝光值,我觉得偏亮/偏暗了,给我调一下。”

我在项目中遇到过这样一个场景:拍摄雪景时,自动曝光总是偏暗。因为相机以为画面太亮,自动降低了曝光。这时候就需要AE补偿,把补偿值调高1-2档。

// 设置AE补偿
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 6); // 补偿值,单位是1/3档

// 获取补偿范围
Range<Integer> compensationRange = characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
// 获取补偿步长
Rational step = characteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP);

避坑指南:我曾经在某个设备上发现补偿值设置后没效果。后来查文档才发现,有些设备在 AE_MODE_OFF 下不支持补偿。所以一定要先检查 CONTROL_AE_AVAILABLE_MODES

13.3 AE锁定:稳定曝光的利器

AE锁定,就是让相机保持当前的曝光参数不变。你想想看,当你对准一个场景,半按快门时,如果曝光还在跳来跳去,那画面就会忽明忽暗。

AE锁定的实现方式有两种:

  • 通过 CONTROL_AE_LOCK:直接设置 true/false。简单粗暴。
  • 通过 CONTROL_AE_PRECAPTURE_TRIGGER:触发预捕获,然后锁定。适合HDR场景。
// 锁定AE
builder.set(CaptureRequest.CONTROL_AE_LOCK, true);

// 检查是否支持锁定
Boolean supportsLock = characteristics.get(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE);
if (supportsLock != null && supportsLock) {
    // 可以锁定
}

注意:AE锁定后,曝光时间和ISO都不会变。但如果场景光线变化剧烈,画面可能会过曝或欠曝。所以锁定前一定要确认场景稳定。

13.4 手动曝光时间设置:从自动到专业的跨越

手动设置曝光时间,说白了就是告诉相机:“你别管了,我就用这个快门速度。”

实现方式很简单:把 CONTROL_AE_MODE 设为 AE_MODE_OFF,然后设置 SENSOR_EXPOSURE_TIME

// 切换到手动曝光
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
// 设置曝光时间,单位是纳秒
long exposureTimeNs = 100000000L; // 100ms
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposureTimeNs);

这里有个坑:曝光时间不是随便设的。每个传感器都有最小和最大曝光时间。我建议先查一下:

Range<Long> exposureRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
long minExposure = exposureRange.getLower();
long maxExposure = exposureRange.getUpper();

经验之谈:手动曝光时间设置后,帧率会受影响。比如你设了200ms曝光,那帧率最多5fps。所以做预览时要注意,别设太长的曝光时间。

13.5 ISO设置与增益控制:敏感度的秘密

ISO就是传感器的感光度。ISO越高,画面越亮,但噪点也越多。增益控制,说白了就是放大信号的过程。

设置ISO同样需要先关掉AE:

// 关掉AE
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
// 设置ISO
builder.set(CaptureRequest.SENSOR_SENSITIVITY, 800); // ISO 800

ISO的范围也要先查:

Range<Integer> isoRange = characteristics.get(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
int minIso = isoRange.getLower();
int maxIso = isoRange.getUpper();

我记得有一次做夜景模式,发现ISO设到3200后噪点完全不可接受。后来改用多帧合成+低ISO的方案,效果好了很多。所以ISO不是越高越好,要权衡。

13.6 知识体系图:曝光控制全景

曝光控制知识体系 曝光控制 AE模式 AE_MODE_ON / ON_AUTO_FLASH AE_MODE_ON_EXTERNAL_FLASH AE补偿 EXPOSURE_COMPENSATION 范围/步长检查 AE锁定 CONTROL_AE_LOCK PRECAPTURE_TRIGGER 手动曝光时间 SENSOR_EXPOSURE_TIME ISO与增益 SENSOR_SENSITIVITY

13.7 实战建议:如何选择曝光策略?

我总结了一个简单的决策流程:

  1. 日常场景:用 AE_MODE_ON,配合AE补偿微调。
  2. 光线复杂场景:先AE锁定,再手动微调曝光时间。
  3. 专业拍摄:关掉AE,完全手动控制曝光时间和ISO。
  4. 夜景/长曝光:手动设置曝光时间(100ms以上),ISO尽量低。

小技巧:如果你不确定当前场景该用多少ISO,可以先让AE跑一帧,然后读取 CONTROL_AE_STATESENSOR_SENSITIVITY,把AE算出来的值作为参考。

好了,曝光控制这块就讲到这里。记住一点:自动曝光是基础,手动控制才是进阶。多在实际项目中尝试不同的组合,你才能真正理解曝光控制的精髓。


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