API de Extensions para CameraX

CameraX proporciona una API de Extensions para acceder a las extensiones que los fabricantes de dispositivos implementaron en varios dispositivos Android. Para obtener una lista de los modos de extensión compatibles, consulta Extensiones de cámara.

Para obtener una lista de los dispositivos que admiten extensiones, consulta la sección Dispositivos compatibles.

Arquitectura de las extensiones

En la siguiente imagen, se muestra la arquitectura de las extensiones de cámara.

Figura 1: Arquitectura de las extensiones de cámara

Una aplicación de CameraX puede usar extensiones a través de la API de Extensions para CameraX. La API de Extensions para CameraX administra las consultas de extensiones disponibles, configura una sesión de cámara de extensión y se comunica con la biblioteca de OEM de extensiones de cámara. Esto permite que la aplicación use funciones como Noche, HDR, Automático, Bokeh o Retoque facial.

Cómo habilitar una extensión para la captura de imágenes y la vista previa

Antes de usar la API de extensiones, recupera una instancia de ExtensionsManager mediante el método ExtensionsManager#getInstanceAsync(Context, CameraProvider). Esto te permitirá consultar la información de disponibilidad de extensiones. Luego, recupera un CameraSelector de extensión habilitada. El modo de extensión se aplicará en los casos de uso de captura de imágenes y de vista previa cuando se llame al método bindToLifecycle() con la extensión CameraSelector habilitada.

Si deseas implementar la extensión para los casos de uso de captura de imágenes y de vista previa, consulta la siguiente muestra de código:

Kotlin

import androidx.camera.extensions.ExtensionMode
import androidx.camera.extensions.ExtensionsManager

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val lifecycleOwner = this

    val cameraProviderFuture = ProcessCameraProvider.getInstance(applicationContext)
    cameraProviderFuture.addListener({
        // Obtain an instance of a process camera provider
        // The camera provider provides access to the set of cameras associated with the device.
        // The camera obtained from the provider will be bound to the activity lifecycle.
        val cameraProvider = cameraProviderFuture.get()

        val extensionsManagerFuture =
            ExtensionsManager.getInstanceAsync(applicationContext, cameraProvider)
        extensionsManagerFuture.addListener({
            // Obtain an instance of the extensions manager
            // The extensions manager enables a camera to use extension capabilities available on
            // the device.
            val extensionsManager = extensionsManagerFuture.get()

            // Select the camera
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            // Query if extension is available.
            // Not all devices will support extensions or might only support a subset of
            // extensions.
            if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.NIGHT)) {
                // Unbind all use cases before enabling different extension modes.
                try {
                    cameraProvider.unbindAll()

                    // Retrieve a night extension enabled camera selector
                    val nightCameraSelector =
                        extensionsManager.getExtensionEnabledCameraSelector(
                            cameraSelector,
                            ExtensionMode.NIGHT
                        )

                    // Bind image capture and preview use cases with the extension enabled camera
                    // selector.
                    val imageCapture = ImageCapture.Builder().build()
                    val preview = Preview.Builder().build()
                    // Connect the preview to receive the surface the camera outputs the frames
                    // to. This will allow displaying the camera frames in either a TextureView
                    // or SurfaceView. The SurfaceProvider can be obtained from the PreviewView.
                    preview.setSurfaceProvider(surfaceProvider)

                    // Returns an instance of the camera bound to the lifecycle
                    // Use this camera object to control various operations with the camera
                    // Example: flash, zoom, focus metering etc.
                    val camera = cameraProvider.bindToLifecycle(
                        lifecycleOwner,
                        nightCameraSelector,
                        imageCapture,
                        preview
                    )
                } catch (e: Exception) {
                    Log.e(TAG, "Use case binding failed", e)
                }
            }
        }, ContextCompat.getMainExecutor(this))
    }, ContextCompat.getMainExecutor(this))
}

Java

import androidx.camera.extensions.ExtensionMode;
import androidx.camera.extensions.ExtensionsManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final LifecycleOwner lifecycleOwner = this;

    final ListenableFuture cameraProviderFuture =
            ProcessCameraProvider.getInstance(getApplicationContext());

    cameraProviderFuture.addListener(() -> {
      try {
          // Obtain an instance of a process camera provider
          // The camera provider provides access to the set of cameras associated with the
          // device. The camera obtained from the provider will be bound to the activity
          // lifecycle.
          final ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

          final ListenableFuture extensionsManagerFuture =
                  ExtensionsManager.getInstanceAsync(getApplicationContext(), cameraProvider);
          extensionsManagerFuture.addListener(() -> {
              // Obtain an instance of the extensions manager
              // The extensions manager enables a camera to use extension capabilities available
              // on the device.
              try {
                  final ExtensionsManager extensionsManager = extensionsManagerFuture.get();

                  // Select the camera
                  final CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;

                  // Query if extension is available.
                  // Not all devices will support extensions or might only support a subset of
                  // extensions.
                  if (extensionsManager.isExtensionAvailable(
                          cameraSelector,
                          ExtensionMode.NIGHT
                  )) {
                      // Unbind all use cases before enabling different extension modes.
                      cameraProvider.unbindAll();

                      // Retrieve extension enabled camera selector
                      final CameraSelector nightCameraSelector = extensionsManager
                              .getExtensionEnabledCameraSelector(cameraSelector, ExtensionMode.NIGHT);

                      // Bind image capture and preview use cases with the extension enabled camera
                      // selector.
                      final ImageCapture imageCapture = new ImageCapture.Builder().build();
                      final Preview preview = new Preview.Builder().build();
                      // Connect the preview to receive the surface the camera outputs the frames
                      // to. This will allow displaying the camera frames in either a TextureView
                      // or SurfaceView. The SurfaceProvider can be obtained from the PreviewView.
                      preview.setSurfaceProvider(surfaceProvider);

                      cameraProvider.bindToLifecycle(
                              lifecycleOwner,
                              nightCameraSelector,
                              imageCapture,
                              preview
                      );
                  }
              } catch (ExecutionException | InterruptedException e) {
                  throw new RuntimeException(e);
              }
          }, ContextCompat.getMainExecutor(this));

      } catch (ExecutionException | InterruptedException e) {
          throw new RuntimeException(e);
      }

  }, ContextCompat.getMainExecutor(this));
}

Cómo inhabilitar la extensión

Para inhabilitar las extensiones de proveedor, desvincula todos los casos de uso y vuelve a vincular los de captura de imágenes y de vista previa con un selector de cámara normal. Por ejemplo, vuelve a vincular la cámara posterior con CameraSelector.DEFAULT_BACK_CAMERA.

Dependencias

La API de Extensions para CameraX se implementa en la biblioteca camera-extensions. Las extensiones dependen de los módulos principales de CameraX (core, camera2, lifecycle).

Groovy

dependencies {
  def camerax_version = "1.2.0-rc01"
  implementation "androidx.camera:camera-core:${camerax_version}"
  implementation "androidx.camera:camera-camera2:${camerax_version}"
  implementation "androidx.camera:camera-lifecycle:${camerax_version}"
  //the CameraX Extensions library
  implementation "androidx.camera:camera-extensions:${camerax_version}"
    ...
}

Kotlin

dependencies {
  val camerax_version = "1.2.0-rc01"
  implementation("androidx.camera:camera-core:${camerax_version}")
  implementation("androidx.camera:camera-camera2:${camerax_version}")
  implementation("androidx.camera:camera-lifecycle:${camerax_version}")
  // the CameraX Extensions library
  implementation("androidx.camera:camera-extensions:${camerax_version}")
    ...
}

Eliminación de la API heredada

Con la nueva API de Extensions versión 1.0.0-alpha26, su API heredada, cuyo lanzamiento fue en agosto de 2019, es ahora obsoleta. A partir de la versión 1.0.0-alpha28, se quitó la API de Extensions heredada de la biblioteca. Las aplicaciones que usan la nueva API de Extensions ahora deben adquirir un CameraSelector habilitado para extensiones y usarlo a fin de vincular los casos de uso.

Las aplicaciones que usan la API de Extensions heredada deben migrar a su nueva versión para garantizar la compatibilidad futura con los próximos lanzamientos de CameraX.

Recursos adicionales

Para obtener más información acerca de CameraX, consulta los siguientes recursos adicionales.

Codelab

  • Cómo comenzar a usar CameraX
  • Muestra de código

    App de ejemplo de extensiones de CameraX

    Otras referencias

    Extensiones de proveedores para CameraX

    Herramienta de validación de extensiones de proveedor para CameraX