19. 手动模式(Pro模式):手动控制ISO、快门速度、对焦距离、白平衡

各位同学,欢迎来到手动模式这一章。说实话,这是整个摄像头采集课程里,我个人最偏爱的一节。为什么?因为当你真正掌握了手动控制,你就不再是「按快门的人」,而是「控制光线的人」。

自动模式固然方便,但机器永远不知道你想要什么效果。你想拍暗部细节?想拉丝流水?想故意过曝营造氛围?这些,都得靠手动模式来实现。

19.1 手动模式的核心思想

手动模式,说白了就是:把摄像头的三个核心参数——ISO、快门速度、对焦距离、白平衡——全部交给开发者控制。系统不再帮你做任何自动决策。

你可能会问:「那岂不是很容易拍砸?」没错,确实容易。但一旦你掌握了规律,你会发现手动模式才是真正的「生产力工具」。

我在项目中遇到过这样一个场景:在室内灯光下做文档扫描,自动模式总是把白纸拍成偏蓝色。后来我手动固定了白平衡,问题立刻解决。嗯,这就是手动模式的价值。

19.2 ISO:感光度的双刃剑

ISO 控制的是传感器对光线的敏感度。数值越高,画面越亮,但噪点也越多。

ISO 值 适用场景 注意事项
100-200 户外阳光充足 画质最佳,几乎无噪点
400-800 室内灯光、阴天 轻微噪点,可接受
1600-3200 暗光环境 噪点明显,建议配合降噪
6400+ 极暗场景 画质严重下降,慎用
我的习惯: 在 Android 上设置 ISO 时,我通常先固定一个基础值(比如 400),然后通过调整快门速度来补偿亮度。不到万不得已,不碰高 ISO。

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); // 纳秒单位
我曾经踩过的坑: 有一次在户外强光下,我设置了很慢的快门速度(1/10 秒),结果画面过曝到全白。后来才意识到,手动模式下系统不会帮你自动调整光圈或 ND 滤镜。所以,快门速度一定要结合当前环境光线来设置。

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_DAYLIGHTAWB_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 手动模式的知识体系

下面这张图,是我自己总结的手动模式控制逻辑。你看一遍,基本就明白各个参数之间的关系了:

手动模式(Pro模式)核心控制逻辑 手动模式控制 ISO 感光度 快门速度 对焦距离 白平衡 控制亮度 & 噪点 控制运动模糊 控制清晰范围 控制色温 ⚠️ 使用手动模式前必须关闭自动控制 CONTROL_AF_MODE → OFF CONTROL_AE_MODE → OFF CONTROL_AWB_MODE → OFF 建议:先固定 ISO 和白平衡,再调整快门速度和对焦距离

19.8 避坑指南

最后,分享几个我亲身踩过的坑:

  • 不要同时调整所有参数。 我习惯先固定 ISO 和白平衡,然后只调快门和对焦。这样出了问题,能快速定位是哪个参数导致的。
  • 注意设备兼容性。 不是所有 Android 设备都支持手动模式。低端机可能不支持 TEMPLATE_MANUAL,记得做降级处理。
  • 预览和成片可能不一致。 有些设备预览流和拍照流是分开的。你手动设置的参数可能只对拍照生效,预览还是自动的。这时候需要检查一下 createCaptureSession 时传入的 Surface 是否正确。
  • 曾经有一次, 我在某款手机上设置了 ISO 100,结果画面暗得几乎看不见。后来发现那款手机的最低 ISO 其实是 200,我设的值被静默忽略了。所以,一定要先通过 CameraCharacteristics 查询设备支持的参数范围。

手动模式,说白了就是「把控制权拿回来」。刚开始可能会不习惯,但一旦上手,你会发现这才是 Android 摄像头开发的真正乐趣所在。