Google is committed to advancing racial equity for Black communities. See how.

Vendor extensions

CameraX provides an API for accessing effects—bokeh, HDR, and others—that have been implemented by phone manufacturers for specific phones. For a device to support vendor extensions, all of the following must be true:

  • The effect has library support from the device OEM.
  • The OEM library is installed on the current device.
  • The OEM library reports the device as supporting the extension.
  • The device has a version of the operating system that the library requires.

You can enable an extension preferentially: if the extension is both supported by and physically on the device, then it will be enabled; otherwise, it will degrade gracefully.

Vendors aren't required to provide an implementation for every effect and feature. Any capability without a vendor-provided implementation defaults to the CameraX implementation. The default implementation reports that the capability is unavailable and skips enabling it.

Extensions architecture

The following image shows the architecture for extensions with CameraX.

Figure 1. CameraX architecture for extensions

Extensions are separate from the Camera2 core of CameraX. In the diagram, the red arrows indicate the main data flow when users trigger an extension-based feature, such as HDR image capture.

Enable an effect for image capture

To apply vendor extensions to CameraX use cases, create an Extender object, which allows you to configure the Builder with the settings for that effect or function. Query the extension for availability, because if an extension is unavailable, the enableExtension() call will not do anything.

To implement the extension for the image capture use case, implement the corresponding image capture extender as shown in the following code sample:

Kotlin

import androidx.camera.extensions.BokehExtender

fun onCreate() {
    // Create a Builder same as in normal workflow.
    val builder = ImageCapture.Builder()

    // Create a camera provider
    val cameraProvider : ProcessCameraProvider = ... // Get the provider instance

    // Create an Extender object which can be used to apply extension
    // configurations.
    val bokehImageCapture = BokehImageCaptureExtender.create(builder)

    // Select the camera
    val cameraSelector = CameraSelector.Builder()
                                       .requireLensFacing(CameraX.LensFacing.BACK)
                                       .build()

    // Query if extension is available (optional).
    if (bokehImageCapture.isExtensionAvailable()) {
        // Enable the extension if available.
        bokehImageCapture.enableExtension()
    }

    // Finish constructing configuration with the same flow as when not using
    // extensions.
    val useCase = ImageCapture.Builder().build()
    cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCase)
}

Java

import androidx.camera.extensions.BokehExtender;

void onCreate() {
    // Create a Builder same as in normal workflow.
    ImageCapture.Builder builder = new ImageCapture.Builder();

    // Create a camera provider
    ProcessCameraProvider cameraProvider = ...; // Get the provider instance

    // Create an Extender object which can be used to apply extension
    // configurations.
    BokehImageCaptureExtender bokehImageCapture = new
            BokehImageCaptureExtender(builder);

    // Select the camera
    CameraSelector cameraSelector = new CameraSelector.Builder().
                                                      .requireLensFacing(CameraX.LensFacing.BACK)
                                                      .build();

    // Query if extension is available (optional).
    if (bokehImageCapture.isExtensionAvailable()) {
        // Enable the extension if available.
        bokehImageCapture.enableExtension();
    }

    // Finish constructing configuration with the same flow as when not using
    // extensions.
    ImageCapture useCase = new ImageCapture.Builder.build();
    cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, useCase);
}

Disable the effect

To disable vendor extensions, create a new instance of the ImageCapture or Preview use case.

Additional resources

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

Codelab

  • Getting Started with CameraX
  • Code sample

  • Official CameraX sample app