核心概念:Camera2 API 的工作流程
在设置参数之前,理解 Camera2 的工作流程至关重要,它是一个基于“请求-响应”模式的 API。

(图片来源网络,侵删)
- 打开相机: 获取
CameraManager,并打开指定的相机设备。 - 创建会话: 创建
CameraCaptureSession,这个会话是相机设备与输出目标(如Surface,用于预览或拍照)之间的桥梁。 - 构建请求: 创建
CaptureRequest。这就是设置参数的核心,你可以把它想象成一个“拍照指令”,里面包含了你想要的所有设置(如曝光、对焦、白平衡等)。 - 提交请求: 将构建好的
CaptureRequest提交到CameraCaptureSession中,相机处理完请求后,会返回一个CaptureResult,其中包含了当前实际的参数值。 - 重复循环: 对于预览,你需要不断地重复提交预览请求,对于拍照,你提交一个一次性拍照请求。
常用相机参数设置详解
以下参数都可以在构建 CaptureRequest 时进行设置。
曝光控制
这是最常用的参数之一,控制照片的亮度和细节。
-
曝光模式:
CONTROL_AE_MODE_ON: 自动曝光,相机自动调整快门速度和 ISO。CONTROL_AE_MODE_OFF: 关闭自动曝光,你需要手动设置SENSOR_EXPOSURE_TIME和SENSOR_SENSITIVITY。CONTROL_AE_MODE_ON_AUTO_FLASH: 自动曝光并自动开启闪光灯。CONTROL_AE_MODE_ON_ALWAYS_FLASH: 自动曝光并强制开启闪光灯。CONTROL_AE_MODE_ON_EXTERNAL_FLASH: 自动曝光并使用外置闪光灯。
-
手动曝光参数 (当
CONTROL_AE_MODE_OFF时生效):
(图片来源网络,侵删)SENSOR_EXPOSURE_TIME: 快门时间,单位是纳秒。1/1000s1000000000纳秒,值越小,进光量越少,画面越暗。SENSOR_SENSITIVITY: ISO 值。100,200,400,800,值越高,传感器对光线越敏感,但噪点也可能越多。
-
曝光补偿:
CONTROL_AE_EXPOSURE_COMPENSATION: 在自动曝光模式下,你可以用它来微调亮度,单位是 EV (Exposure Value),通常范围在-2.0到+2.0之间,步长为1/3或1/2,正值变亮,负值变暗。
代码示例 (设置自动曝光模式):
// requestBuilder 是 CaptureRequest.Builder 的实例 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
对焦控制
控制相机的清晰度。
-
对焦模式:
CONTROL_AF_MODE_OFF: 关闭自动对焦,适用于固定焦距的设备。CONTROL_AF_MODE_AUTO: 单次自动对焦,对焦一次后锁定,适用于拍照。CONTROL_AF_MODE_CONTINUOUS_PICTURE: 连续自动对焦(照片模式),相机持续对焦,适合拍摄移动物体。CONTROL_AF_MODE_CONTINUOUS_VIDEO: 连续自动对焦(视频模式),对焦速度更快,以适应视频拍摄。
-
触发对焦:
- 你可以通过设置
CONTROL_AF_TRIGGER来手动触发一次对焦。CONTROL_AF_TRIGGER_START: 开始对焦。CONTROL_AF_TRIGGER_CANCEL: 取消对焦。
- 对焦完成后,你会收到
CameraCaptureSession.CaptureCallback的onCaptureCompleted回调,result.get(CaptureResult.CONTROL_AF_STATE)会告诉你对焦状态(如AF_STATE_FOCUSED_LOCKED)。
- 你可以通过设置
代码示例 (设置连续对焦模式):
requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
白平衡
控制照片的色彩还原。
-
白平衡模式:
CONTROL_AWB_MODE_AUTO: 自动白平衡,相机自动判断光源色温。CONTROL_AWB_MODE_OFF: 关闭自动白平衡,需要手动设置COLOR_TEMPERATURE。CONTROL_AWB_MODE_INCANDESCENT: 钨丝灯模式。CONTROL_AWB_MODE_FLUORESCENT: 荧光灯模式。CONTROL_AWB_MODE_DAYLIGHT: 日光模式。CONTROL_AWB_MODE_CLOUDY_DAYLIGHT: 阴天模式。
-
手动色温 (当
CONTROL_AWB_MODE_OFF时生效):COLOR_TEMPERATURE: 色温值,单位是开尔文,烛光约 2000K,日光约 5500K,阴天约 6500K,值越低,画面越暖(偏黄);值越高,画面越冷(偏蓝)。
代码示例 (设置自动白平衡):
requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
闪光灯
- 闪光灯模式:
CONTROL_AE_MODE_ON是前提。FLASH_MODE_OFF: 关闭闪光灯。FLASH_MODE_ON: 强制开启闪光灯。FLASH_MODE_AUTO: 自动模式,根据环境光决定是否开启。FLASH_MODE_TORCH: 手电筒模式,闪光灯常亮,不拍照时使用。
代码示例 (设置自动闪光灯):
// 首先设置AE模式为带闪光灯的自动 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // 然后设置闪光灯模式 requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_AUTO);
图缩放
实现变焦功能。
- 缩放比例:
SCALER_CROP_REGION: 定义一个裁剪区域,实现数码变焦,这个区域是一个Rect,相对于传感器全尺寸。- 变焦比例 = 传感器全尺寸 / 裁剪区域尺寸。
- 传感器尺寸为
(4000, 3000),你想 2 倍变焦,裁剪区域可以是(2000, 1500),中心点与传感器中心相同。
代码示例 (实现 2 倍变焦):
// 获取传感器信息
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
Rect sensorRect = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
// 计算裁剪区域
int centerX = sensorRect.width() / 2;
int centerY = sensorRect.height() / 2;
int cropWidth = sensorRect.width() / 2;
int cropHeight = sensorRect.height() / 2;
Rect cropRect = new Rect(centerX - cropWidth / 2, centerY - cropHeight / 2,
centerX + cropWidth / 2, centerY + cropHeight / 2);
// 设置缩放区域
requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRect);
拍照模式
CONTROL_CAPTURE_INTENT:INTENT_PREVIEW: 预览模式,优化速度和流畅度。INTENT_STILL_CAPTURE: 静态拍照模式,优化图像质量和信噪比。INTENT_VIDEO_RECORD: 视频模式,优化稳定性和对焦性能。
代码示例 (设置拍照模式):
// 在拍照请求中设置 requestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
完整代码示例:创建一个带参数的拍照请求
假设你已经完成了相机打开、会话创建等前置步骤。
// 1. 获取 CaptureRequest.Builder
// 假设 cameraDevice 是已打开的 CameraDevice
CaptureRequest.Builder previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
CaptureRequest.Builder captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
// 2. 将预览 Surface 添加到请求中
// previewSurface 是用于显示预览的 Surface
previewRequestBuilder.addTarget(previewSurface);
captureRequestBuilder.addTarget(imageReader.getSurface()); // imageReader 用于获取拍照数据
// 3. 设置各种参数
// --- 曝光 ---
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// --- 对焦 ---
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
// 手动触发一次对焦
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_START);
// --- 白平衡 ---
previewRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
captureRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
// --- 闪光灯 (在拍照请求中) ---
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_AUTO);
// --- 拍照模式 ---
captureRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
// 4. 构建请求
CaptureRequest previewRequest = previewRequestBuilder.build();
CaptureRequest captureRequest = captureRequestBuilder.build();
// 5. 提交请求
// 在 CameraCaptureSession 中提交
// session 是 CameraCaptureSession 实例
session.setRepeatingRequest(previewRequest, null, null); // 设置预览请求,循环执行
// 当用户点击拍照时,提交拍照请求
session.capture(captureRequest, new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
// 拍照完成后的处理
// 可以在这里检查对焦状态 result.get(CaptureResult.CONTROL_AF_STATE)
Log.d("Camera", "Photo captured!");
}
}, null);
旧版 Camera API (简要提及)
对于旧项目或需要兼容非常老的设备,你可能还会遇到 Camera API,它的参数设置方式完全不同。
- 获取参数对象:
Camera.Parameters parameters = camera.getParameters(); - 设置参数: 直接调用
Parameters对象的方法。- 曝光:
parameters.setExposureCompensation(evValue); - 对焦:
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); - 闪光灯:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO); - 场景模式:
parameters.setSceneMode(Camera.Parameters.SCENE_MODE_NIGHT); - 图片尺寸:
parameters.setPictureSize(width, height);
- 曝光:
- 应用参数:
camera.setParameters(parameters);
重要提示: Camera API 是同步的,设置参数可能会阻塞 UI 线程,并且很多操作(如切换对焦模式)需要先停止预览,设置完后再重新开始,非常繁琐且容易出错。强烈建议新项目使用 Camera2 API。
最佳实践与注意事项
- 异步操作:
Camera2API 是完全异步的,所有操作(打开、设置、回调)都要在异步线程中处理,避免阻塞主线程。 - 检查设备支持: 不是所有设备都支持所有参数,在设置前,必须通过
CameraCharacteristics检查设备是否支持该参数。if (characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES).contains(CaptureRequest.CONTROL_AE_MODE_OFF)) { // 设备支持手动曝光 } - 生命周期管理: 在
Activity/Fragment的onPause()或onStop()中必须正确关闭相机设备 (cameraDevice.close()),否则会导致严重问题。 - 权限: 别忘了在
AndroidManifest.xml中声明相机权限。<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 如果需要自动对焦 -->
- 性能: 频繁地创建和销毁
CameraCaptureSession会影响性能,通常在相机生命周期内只创建一次会话,通过重复提交不同的CaptureRequest来改变行为。
希望这份详细的指南能帮助你全面掌握 Android 相机参数的设置!
