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 知识体系图:曝光控制全景
13.7 实战建议:如何选择曝光策略?
我总结了一个简单的决策流程:
- 日常场景:用
AE_MODE_ON,配合AE补偿微调。 - 光线复杂场景:先AE锁定,再手动微调曝光时间。
- 专业拍摄:关掉AE,完全手动控制曝光时间和ISO。
- 夜景/长曝光:手动设置曝光时间(100ms以上),ISO尽量低。
小技巧:如果你不确定当前场景该用多少ISO,可以先让AE跑一帧,然后读取 CONTROL_AE_STATE 和 SENSOR_SENSITIVITY,把AE算出来的值作为参考。
好了,曝光控制这块就讲到这里。记住一点:自动曝光是基础,手动控制才是进阶。多在实际项目中尝试不同的组合,你才能真正理解曝光控制的精髓。
公众号:蓝海资料掘金营,微信deep3321