Android camera参数如何正确设置?

99ANYc3cd6
预计阅读时长 29 分钟
位置: 首页 参数 正文

核心概念:Camera2 API 的工作流程

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

Android camera 参数设置
(图片来源网络,侵删)
  1. 打开相机: 获取 CameraManager,并打开指定的相机设备。
  2. 创建会话: 创建 CameraCaptureSession,这个会话是相机设备与输出目标(如 Surface,用于预览或拍照)之间的桥梁。
  3. 构建请求: 创建 CaptureRequest这就是设置参数的核心,你可以把它想象成一个“拍照指令”,里面包含了你想要的所有设置(如曝光、对焦、白平衡等)。
  4. 提交请求: 将构建好的 CaptureRequest 提交到 CameraCaptureSession 中,相机处理完请求后,会返回一个 CaptureResult,其中包含了当前实际的参数值。
  5. 重复循环: 对于预览,你需要不断地重复提交预览请求,对于拍照,你提交一个一次性拍照请求。

常用相机参数设置详解

以下参数都可以在构建 CaptureRequest 时进行设置。

曝光控制

这是最常用的参数之一,控制照片的亮度和细节。

  • 曝光模式:

    • CONTROL_AE_MODE_ON: 自动曝光,相机自动调整快门速度和 ISO。
    • CONTROL_AE_MODE_OFF: 关闭自动曝光,你需要手动设置 SENSOR_EXPOSURE_TIMESENSOR_SENSITIVITY
    • CONTROL_AE_MODE_ON_AUTO_FLASH: 自动曝光并自动开启闪光灯。
    • CONTROL_AE_MODE_ON_ALWAYS_FLASH: 自动曝光并强制开启闪光灯。
    • CONTROL_AE_MODE_ON_EXTERNAL_FLASH: 自动曝光并使用外置闪光灯。
  • 手动曝光参数 (当 CONTROL_AE_MODE_OFF 时生效):

    Android camera 参数设置
    (图片来源网络,侵删)
    • SENSOR_EXPOSURE_TIME: 快门时间,单位是纳秒。1/1000s 1000000000 纳秒,值越小,进光量越少,画面越暗。
    • SENSOR_SENSITIVITY: ISO 值。100, 200, 400, 800,值越高,传感器对光线越敏感,但噪点也可能越多。
  • 曝光补偿:

    • CONTROL_AE_EXPOSURE_COMPENSATION: 在自动曝光模式下,你可以用它来微调亮度,单位是 EV (Exposure Value),通常范围在 -2.0+2.0 之间,步长为 1/31/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.CaptureCallbackonCaptureCompleted 回调,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,它的参数设置方式完全不同。

  1. 获取参数对象: Camera.Parameters parameters = camera.getParameters();
  2. 设置参数: 直接调用 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);
  3. 应用参数: camera.setParameters(parameters);

重要提示: Camera API 是同步的,设置参数可能会阻塞 UI 线程,并且很多操作(如切换对焦模式)需要先停止预览,设置完后再重新开始,非常繁琐且容易出错。强烈建议新项目使用 Camera2 API。


最佳实践与注意事项

  1. 异步操作: Camera2 API 是完全异步的,所有操作(打开、设置、回调)都要在异步线程中处理,避免阻塞主线程。
  2. 检查设备支持: 不是所有设备都支持所有参数,在设置前,必须通过 CameraCharacteristics 检查设备是否支持该参数。
    if (characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES).contains(CaptureRequest.CONTROL_AE_MODE_OFF)) {
        // 设备支持手动曝光
    }
  3. 生命周期管理: 在 Activity/FragmentonPause()onStop() 中必须正确关闭相机设备 (cameraDevice.close()),否则会导致严重问题。
  4. 权限: 别忘了在 AndroidManifest.xml 中声明相机权限。
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 如果需要自动对焦 -->
  5. 性能: 频繁地创建和销毁 CameraCaptureSession 会影响性能,通常在相机生命周期内只创建一次会话,通过重复提交不同的 CaptureRequest 来改变行为。

希望这份详细的指南能帮助你全面掌握 Android 相机参数的设置!

-- 展开阅读全文 --
头像
Dell Vostro 15-3559拆机步骤是怎样的?
« 上一篇 12-03
Android如何给Service传参数?
下一篇 » 12-03
取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]