图像捕获

图像捕获用例旨在捕获高分辨率、高质量的照片,并提供自动白平衡、自动曝光和自动对焦 (3A) 功能,此外还提供简单的手动相机控制。调用方负责决定如何使用捕获的图片,包括以下选项

ImageCapture 运行在两种类型的可自定义执行器上,回调执行器和 IO 执行器。

  • 回调执行器是 takePicture 方法的参数。它用于执行用户提供的 OnImageCapturedCallback()
  • 如果调用方选择将图像保存到文件位置,您可以指定一个执行器来执行 IO 操作。要设置 IO 执行器,请调用 ImageCapture.Builder.setIoExecutor(Executor)。如果执行器不存在,CameraX 将默认为内部 IO 执行器来执行此任务。

设置图像捕获

图像捕获提供拍摄照片的基本控制,例如闪光灯、连续自动对焦、零快门延迟等。

setCaptureMode()

使用 ImageCapture.Builder.setCaptureMode() 在拍摄照片时配置捕获模式

捕获模式默认为 CAPTURE_MODE_MINIMIZE_LATENCY。有关更多信息,请参阅 setCaptureMode() 参考文档。

零快门延迟

从 1.2 版开始,零快门延迟 (CAPTURE_MODE_ZERO_SHOT_LAG) 可作为捕获模式使用。启用零快门延迟后,与默认捕获模式 CAPTURE_MODE_MINIMIZE_LATENCY 相比,延迟显着降低,因此您永远不会错过拍摄时机。

零快门延迟使用环形缓冲区存储三个最新的捕获帧。当用户按下捕获按钮时,CameraX 会调用 takePicture(),并且环形缓冲区会检索时间戳最接近按钮按下时间戳的捕获帧。然后,CameraX 会 重新处理 捕获会话以从该帧生成图像,该图像将以 JPEG 格式保存到磁盘。

先决条件

在启用零快门延迟之前,请使用 isZslSupported() 确定您的设备是否满足以下要求

对于不满足最低要求的设备,CameraX 将回退到 CAPTURE_MODE_MINIMIZE_LATENCY

零快门延迟仅适用于 图像捕获 用例。您不能在 视频捕获 用例或使用 相机扩展 时启用它。最后,由于使用闪光灯会导致更大的延迟,因此在闪光灯打开或自动模式下,零快门延迟不起作用。有关设置闪光灯模式的更多信息,请参阅 setFlashMode()

启用零快门延迟

要启用零快门延迟,请将 CAPTURE_MODE_ZERO_SHOT_LAG 传递给 ImageCapture.Builder.setCaptureMode()。如果失败,setCaptureMode() 将回退到 CAPTURE_MODE_MINIMIZE_LATENCY

setFlashMode()

默认闪光灯模式为 FLASH_MODE_OFF。要设置闪光灯模式,请使用 ImageCapture.Builder.setFlashMode()

拍摄照片

以下代码示例演示如何配置您的应用以拍摄照片

Kotlin

val imageCapture = ImageCapture.Builder()
    .setTargetRotation(view.display.rotation)
    .build()

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture,
    imageAnalysis, preview)

Java

ImageCapture imageCapture =
    new ImageCapture.Builder()
        .setTargetRotation(view.getDisplay().getRotation())
        .build();

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture, imageAnalysis, preview);

请注意,bindToLifecycle() 返回一个 Camera 对象。有关控制相机输出(例如缩放和曝光)的更多信息,请参阅 本指南

配置完相机后,以下代码根据用户操作拍摄照片

Kotlin

fun onClick() {
    val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(...)).build()
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        object : ImageCapture.OnImageSavedCallback {
            override fun onError(error: ImageCaptureException)
            {
                // insert your code here.
            }
            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                // insert your code here.
            }
        })
}

Java

public void onClick() {
    ImageCapture.OutputFileOptions outputFileOptions =
            new ImageCapture.OutputFileOptions.Builder(new File(...)).build();
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        new ImageCapture.OnImageSavedCallback() {
            @Override
            public void onImageSaved(ImageCapture.OutputFileResults outputFileResults) {
                // insert your code here.
            }
            @Override
            public void onError(ImageCaptureException error) {
                // insert your code here.
            }
       }
    );
}

图像捕获方法完全支持 JPEG 格式。有关显示如何将 Media.Image 对象从 YUV_420_888 格式转换为 RGB Bitmap 对象的示例代码,请参阅 YuvToRgbConverter.kt

其他资源

要了解有关 CameraX 的更多信息,请参阅以下其他资源。

Codelab

  • CameraX 入门
  • 代码示例

  • CameraX 示例应用