图片拍摄用例旨在拍摄高分辨率的优质照片,不仅提供简单的相机手动控制功能,还提供自动白平衡、自动曝光和自动对焦 (3A) 功能。调用方负责决定如何使用拍摄的照片,具体包括以下选项:
takePicture(Executor, OnImageCapturedCallback)
:此方法为拍摄的图片提供内存缓冲区。takePicture(OutputFileOptions, Executor, OnImageSavedCallback)
:此方法将拍摄的图片保存到提供的文件位置。
运行 ImageCapture
的可自定义执行程序有两种类型:回调执行程序和 IO 执行程序。
- 回调执行程序是
takePicture
方法的参数。它用于执行用户提供的OnImageCapturedCallback()
。 - 如果调用方选择将图片保存到文件位置,您可以指定执行程序以执行 IO。如需设置 IO 执行程序,请调用
ImageCapture.Builder.setIoExecutor(Executor)
。如果执行程序不存在,则默认 CameraX 为任务的内部 IO 执行程序。
设置图片拍摄
图片拍摄用例会提供拍照所需的基本控件,例如闪光灯、连续自动对焦、零快门延迟等。
setCaptureMode()
ImageCapture.Builder.setCaptureMode()
可用于配置拍摄照片时所采用的拍摄模式:
CAPTURE_MODE_MINIMIZE_LATENCY
:缩短图片拍摄的延迟时间。CAPTURE_MODE_MAXIMIZE_QUALITY
:提高图片拍摄的图片质量。
拍摄模式默认为 CAPTURE_MODE_MINIMIZE_LATENCY
。如需了解详情,请参阅 setCaptureMode()
参考文档。
零快门延迟
从 1.2 开始,零快门延迟 (CAPTURE_MODE_ZERO_SHOT_LAG
) 以拍摄模式的形式提供。与默认拍摄模式 CAPTURE_MODE_MINIMIZE_LATENCY
相比,启用零快门延迟后,延迟时间会明显缩短,这样您便不会错过拍摄机会。
零快门延迟会使用环形缓冲区来存储三个最近拍摄的帧。当用户按下拍摄按钮时,CameraX 会调用 takePicture()
,环形缓冲区则会检索其时间戳最接近按钮按下时间的捕获帧。然后,CameraX 会重新处理拍摄会话,以从该帧生成以 JPEG 格式保存到磁盘的图片。
前提条件
在启用零快门延迟之前,请使用 isZslSupported()
确定相关设备是否符合以下要求:
- 以 Android 6.0 及更高版本(API 级别 23 及更高级别)为目标平台。
- 支持
PRIVATE
重新处理。
如果设备不符合最低要求,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()
:
FLASH_MODE_ON
:闪光灯始终处于开启状态。FLASH_MODE_AUTO
:在弱光环境下拍摄时,自动开启闪光灯。
拍照
以下代码示例展示了如何配置应用来拍摄照片:
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
代码示例