这个系列文章我们来介绍一位海外工程师如何探索 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()
。
音视频方向学习、求职,欢迎加入我们的星球
丰富的音视频知识、面试题、技术方案干货分享,还可以进行面试辅导

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