19. 手动模式(Pro模式):手动控制ISO、快门速度、对焦距离、白平衡
各位同学,欢迎来到手动模式这一章。说实话,这是整个摄像头采集课程里,我个人最偏爱的一节。为什么?因为当你真正掌握了手动控制,你就不再是「按快门的人」,而是「控制光线的人」。
自动模式固然方便,但机器永远不知道你想要什么效果。你想拍暗部细节?想拉丝流水?想故意过曝营造氛围?这些,都得靠手动模式来实现。
19.1 手动模式的核心思想
手动模式,说白了就是:把摄像头的三个核心参数——ISO、快门速度、对焦距离、白平衡——全部交给开发者控制。系统不再帮你做任何自动决策。
你可能会问:「那岂不是很容易拍砸?」没错,确实容易。但一旦你掌握了规律,你会发现手动模式才是真正的「生产力工具」。
我在项目中遇到过这样一个场景:在室内灯光下做文档扫描,自动模式总是把白纸拍成偏蓝色。后来我手动固定了白平衡,问题立刻解决。嗯,这就是手动模式的价值。
19.2 ISO:感光度的双刃剑
ISO 控制的是传感器对光线的敏感度。数值越高,画面越亮,但噪点也越多。
| ISO 值 | 适用场景 | 注意事项 |
|---|---|---|
| 100-200 | 户外阳光充足 | 画质最佳,几乎无噪点 |
| 400-800 | 室内灯光、阴天 | 轻微噪点,可接受 |
| 1600-3200 | 暗光环境 | 噪点明显,建议配合降噪 |
| 6400+ | 极暗场景 | 画质严重下降,慎用 |
19.3 快门速度:凝固时间还是记录轨迹
快门速度决定了传感器曝光的时间长短。速度快,能凝固运动;速度慢,能拍出光轨、流水等动态效果。
但这里有个坑:快门速度太慢,手持拍摄会糊片。一般安全快门是 1/焦距 秒。比如你用 50mm 镜头,快门不要低于 1/50 秒。
在 Android 的 Camera2 API 中,快门速度的单位是纳秒。1 秒 = 1,000,000,000 纳秒。所以 1/30 秒就是 33,333,333 纳秒。
// 设置快门速度为 1/30 秒
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 33333333L); // 纳秒单位
19.4 对焦距离:从微距到无穷远
对焦距离控制的是镜头到被摄物体的清晰成像距离。在 Camera2 中,我们通过 LENS_FOCUS_DISTANCE 来控制,单位是米(的倒数,即屈光度)。
简单来说:
- 0.0f:无穷远对焦(拍风景)
- 1.0f:对焦在 1 米处
- 10.0f:对焦在 0.1 米处(微距)
你想想看,如果你在做扫码功能,自动对焦总是对到背景上,多烦人?手动固定对焦距离,扫码成功率直接翻倍。
// 手动设置对焦距离为 0.5 米
builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 2.0f); // 1/0.5 = 2.0 屈光度
// 注意:必须先关闭自动对焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
CONTROL_AF_MODE 设为 OFF。否则你设了也白设,系统会自动覆盖掉。
19.5 白平衡:让白色真正是白色
白平衡解决的是「色温」问题。日光灯下偏蓝,白炽灯下偏黄。自动白平衡虽然方便,但在混合光源下经常翻车。
Camera2 中通过 CONTROL_AWB_MODE 来控制,也可以手动设置色温值:
| 色温值(K) | 光源类型 | 效果 |
|---|---|---|
| 2500-3500 | 白炽灯 | 暖色调 |
| 5000-5500 | 日光 | 中性白 |
| 6000-7500 | 阴天/荧光灯 | 冷色调 |
// 手动设置白平衡为 5500K(日光)
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.0f, // R
1.0f, // G
1.0f, // G
1.0f // B
));
CONTROL_AWB_MODE 的预设模式,比如 AWB_MODE_DAYLIGHT、AWB_MODE_FLUORESCENT 等。这比完全自动要稳定得多。
19.6 完整的手动模式配置流程
好了,我们把上面四个参数串起来,写一个完整的手动模式配置示例:
private void setupManualMode(CameraDevice cameraDevice) {
try {
CaptureRequest.Builder builder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL);
// 1. 关闭自动对焦
builder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
builder.set(CaptureRequest.LENS_FOCUS_DISTANCE, 2.0f); // 对焦在 0.5 米
// 2. 关闭自动曝光,手动控制 ISO 和快门
builder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
builder.set(CaptureRequest.SENSOR_SENSITIVITY, 400); // ISO 400
builder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, 33333333L); // 1/30 秒
// 3. 关闭自动白平衡
builder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
builder.set(CaptureRequest.COLOR_CORRECTION_MODE,
CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
// 4. 设置输出 Surface
builder.addTarget(surfaceView.getHolder().getSurface());
// 5. 创建会话并开始预览
cameraDevice.createCaptureSession(Arrays.asList(surfaceView.getHolder().getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
session.setRepeatingRequest(builder.build(), null, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
// ... 其他回调
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
19.7 手动模式的知识体系
下面这张图,是我自己总结的手动模式控制逻辑。你看一遍,基本就明白各个参数之间的关系了:
19.8 避坑指南
最后,分享几个我亲身踩过的坑:
- 不要同时调整所有参数。 我习惯先固定 ISO 和白平衡,然后只调快门和对焦。这样出了问题,能快速定位是哪个参数导致的。
- 注意设备兼容性。 不是所有 Android 设备都支持手动模式。低端机可能不支持
TEMPLATE_MANUAL,记得做降级处理。 - 预览和成片可能不一致。 有些设备预览流和拍照流是分开的。你手动设置的参数可能只对拍照生效,预览还是自动的。这时候需要检查一下
createCaptureSession时传入的 Surface 是否正确。 - 曾经有一次, 我在某款手机上设置了 ISO 100,结果画面暗得几乎看不见。后来发现那款手机的最低 ISO 其实是 200,我设的值被静默忽略了。所以,一定要先通过
CameraCharacteristics查询设备支持的参数范围。
手动模式,说白了就是「把控制权拿回来」。刚开始可能会不习惯,但一旦上手,你会发现这才是 Android 摄像头开发的真正乐趣所在。