Image capture

The image capture use case is designed for capturing high-resolution, high-quality photos and provides auto-white-balance, auto-exposure, and auto-focus (3A) functionality, in addition to simple manual camera controls. The caller is responsible for deciding how to use the captured picture, including the following options:

There are two types of customizable executors on which ImageCapture runs, the callback executor and the IO executor.

  • The callback executor is the parameter of the takePicture methods. It is used to execute the user-provided OnImageCapturedCallback().
  • If the caller chooses to save the image to a file location, you can specify an executor to do the IO. To set the IO executor, call ImageCapture.Builder.setIoExecutor(Executor). If the executor is absent, CameraX will default to an internal IO executor for the task.

Set up image capture

Image capture provides basic controls for taking pictures, such as flash, continuous auto-focus, zero-shutter lag, and more.

setCaptureMode()

Use ImageCapture.Builder.setCaptureMode() to configure the capture mode when taking a photo:

The capture mode defaults to CAPTURE_MODE_MINIMIZE_LATENCY. For more information, see the setCaptureMode() reference documentation.

Zero-Shutter Lag

Starting in 1.2, Zero-Shutter Lag (CAPTURE_MODE_ZERO_SHOT_LAG) is available as a capture mode. With Zero-Shutter Lag enabled, latency is significantly reduced compared to the default capture mode, CAPTURE_MODE_MINIMIZE_LATENCY, so that you will never miss the shot.

Zero-Shutter Lag uses a ring buffer that stores the three most recent capture frames. When a user presses the capture button, CameraX invokes takePicture(), and the ring buffer retrieves the captured frame with the timestamp that is closest to that of the button press. CameraX then reprocesses the capture session to generate an image from that frame, which is saved to disk in JPEG format.

Prerequisites

Before enabling Zero-Shutter Lag, use isZslSupported() to determine if your device meets the following requirements:

For devices that do not meet the minimum requirements, CameraX falls back to CAPTURE_MODE_MINIMIZE_LATENCY.

Zero-Shutter Lag is only available for the Image capture use case. You cannot enable it for the Video capture use case or with Camera extensions. Finally, because using flash results in greater latency, Zero-Shutter Lag does not work when flash is ON or in AUTO mode. For more information about setting the flash mode, see setFlashMode().

Enable Zero-Shutter Lag

To enable Zero-Shutter Lag, pass CAPTURE_MODE_ZERO_SHOT_LAG to ImageCapture.Builder.setCaptureMode(). If unsuccessful, setCaptureMode() falls back to CAPTURE_MODE_MINIMIZE_LATENCY.

setFlashMode()

The default flash mode is FLASH_MODE_OFF. To set the flash mode, use ImageCapture.Builder.setFlashMode():

Take photo

The following code sample shows how to configure your app to take a photo:

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);

Note that bindToLifecycle() returns a Camera object. See this guide for more information about controlling camera output, such as zoom and exposure.

Once you've configured the camera, the following code takes a photo based on user action:

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.
            }
       }
    );
}

The image capture method fully supports the JPEG format. For sample code that shows how to convert a Media.Image object from YUV_420_888 format to an RGB Bitmap object, see YuvToRgbConverter.kt.

Additional resources

To learn more about CameraX, consult the following additional resources.

Codelab

  • Getting Started with CameraX
  • Code sample

  • CameraX sample apps