探索 CameraX 音视频相机技术(4):捕获图像

这个系列文章我们来介绍一位海外工程师如何探索 CameraX 音视频相机技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,这是第 4 篇:CameraX 捕获图像。

—— 来自公众号关键帧Keyframe的分享

1、关键概念

本文主要讨论以下概念:

  • 存储方法 :可以将图像捕获到内存缓冲区或直接保存到文件中。
  • 执行器 :ImageCapture 使用执行器来处理回调和 I/O 操作。可以自定义这些执行器以提高性能和控制能力。
  • 捕获模式 :可以配置捕获模式以优化延迟或图像质量。

1.1、存储方法

使用 ImageCapture 捕获图像有两种方式,它们分别使用 ImageCapture.takePicture() 的重载方法:

  • 文件 :使用 takePicture(OutputFileOptions, Executor, OnImageSavedCallback) 将捕获的图像直接保存到磁盘上的文件中。
    • 这是最常见的拍照方式。
  • 内存中 :使用 takePicture(Executor, OnImageCapturedCallback) 接收捕获图像的内存缓冲区。
    • 这对于实时图像处理或分析非常有用。

1.2、执行器

调用 takePicture 时,需要传递一个 Executor 以及 OnImageCapturedCallback 或 OnImageSavedCallback 函数。Executor 运行回调并处理任何结果 IO。

2、拍照

要拍照,需要先设置相机,然后调用 takePicture

2.1、设置相机

要设置相机,请创建一个 CameraProvider,然后创建一个 ImageCapture 对象。使用 ImageCapture.Builder()

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

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, imageCapture, preview)
ImageCapture imageCapture = new ImageCapture.Builder()
    .setTargetRotation(view.getDisplay().getRotation())
    .build();

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

2.2 拍照

配置好相机后,调用 takePicture() 捕获图像。以下示例展示了如何使用 takePicture() 将图像保存到磁盘:

fun onClick() {
    val outputFileOptions = ImageCapture.OutputFileOptions.Builder(File(...)).build()
    imageCapture.takePicture(outputFileOptions, cameraExecutor,
        object : ImageCapture.OnImageSavedCallback {
            override fun onError(error: ImageCaptureException) {
                // 在此处插入代码
            }
            override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
                // 在此处插入代码
            }
        })
}
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) {
                // 在此处插入代码
            }
            @Override
            public void onError(ImageCaptureException error) {
                // 在此处插入代码
            }
       }
    );
}

以下是此代码片段的关键点:

  • ImageCapture.OutputFileOptions 允许你配置保存位置和元数据。
    • 在这里,OutputFileOptions.Builder() 使用 File 对象来确定保存位置。
  • takePicture() 函数使用提供的选项和执行器异步捕获图像。
  • OnImageSavedCallback 提供成功和失败的回调。
    • onImageSaved() 回调处理成功的图像捕获并提供对保存图像结果的访问。
    • onError() 回调处理图像捕获错误。

以下是使用 ImageCapture 配置设备相机的其他方法。你可以使用 ImageCapture.Builder 方法来实现这些配置。

3、设置捕获模式

使用 ImageCapture.Builder.setCaptureMode() 配置拍照时的捕获模式:

  • CAPTURE_MODE_MINIMIZE_LATENCY :优化图像捕获以减少延迟。
  • CAPTURE_MODE_MAXIMIZE_QUALITY :优化图像捕获以提高图像质量。

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

4、设置闪光灯模式

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

  • FLASH_MODE_ON :闪光灯始终开启。
  • FLASH_MODE_AUTO :在低光环境下自动开启闪光灯。

5、启用零快门延迟

从 CameraX 1.2 开始,零快门延迟(Zero-Shutter Lag)作为一种捕获模式可供使用。启用零快门延迟可以显著减少与默认捕获模式相比的延迟,确保你不会错过任何拍摄机会。

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

有关捕获模式的更多信息,请参阅图像捕获指南。

6、工作原理

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

7、先决条件

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

  • 支持 Android 6.0 及以上(API 级别 23 及更高)。
  • 支持 PRIVATE 重处理。

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

零快门延迟仅适用于图像捕获。不能在视频捕获或相机扩展中启用它。

最后,由于使用闪光灯会导致更大的延迟,因此在闪光灯开启或处于自动模式时,零快门延迟无法工作。有关设置闪光灯模式的更多信息,请参阅 setFlashMode()

音视频方向学习、求职,欢迎加入我们的星球

丰富的音视频知识、面试题、技术方案干货分享,还可以进行面试辅导

探索 CameraX 音视频相机技术(4):捕获图像

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论