API de Extensions

CameraX proporciona una API de Extensions para acceder a los siguientes efectos especiales:

  • Automático: Ajusta automáticamente la imagen final en función de su entorno.
  • Bokeh: Permite destacar mejor a las personas en primer plano cuando se toman fotos en modo de retrato.
  • Retoque facial: Empareja el tono de piel y brinda otros efectos faciales cuando se toman fotos estáticas.
  • HDR (alto rango dinámico): Toma fotos con diferentes parámetros de configuración de AE.
  • Nocturno: Toma fotos estáticas en condiciones de poca luz, por lo general, de noche.

que se implementaron en dispositivos Android (teléfonos, tablets, etc.). Para que un dispositivo admita dichas extensiones de proveedores, debe cumplir con los siguientes requisitos:

  • El efecto debe admitir la biblioteca del ROM del dispositivo.
  • La biblioteca del ROM debe estar instalada en el dispositivo actual.
  • El dispositivo debe contar con la versión del sistema operativo que requiera la biblioteca.

Puedes habilitar una extensión de manera preferencial: si la extensión es compatible con el dispositivo y la tienes instalada, entonces estará habilitada. De lo contrario, se ajustará de manera óptima para versiones anteriores.

Los proveedores no tienen la obligación de proporcionar una implementación para cada efecto y función. Toda función que no tenga una implementación proporcionada por el proveedor se agregará de forma predeterminada a la implementación de CameraX. La implementación predeterminada informa que la función no está disponible y omite la habilitación.

Arquitectura de extensiones

En la siguiente imagen, se muestra la arquitectura de extensiones con CameraX.

Figura 1: Arquitectura de CameraX para extensiones

Las extensiones son independientes del núcleo Camera2 de CameraX. En el diagrama, las flechas rojas indican el flujo de datos principal cuando los usuarios activan una función basada en extensiones, como la captura de imágenes HDR.

Habilita un efecto para la captura de imágenes y la vista previa.

Antes de usar la API de extensiones, recupera una instancia de ExtensionsManager con el método ExtensionsManager#getInstance(Context). 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

fun onCreate() {
    // Create a camera provider
    val cameraProvider : ProcessCameraProvider = ... // Get the provider instance

    lifecycleScope.launch {
        // Create an extensions manager
        val extensionsManager = ExtensionsManager.getInstance(lifecycleOwner).await()

        // Select the camera
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        // Query if extension is available.
        if (extensionsManager.isExtensionAvailable(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )
        ) {
            // Unbind all use cases before enabling different extension modes.
            cameraProvider.unbindAll()

            // Retrieve extension enabled camera selector
            val bokehCameraSelector = extensionsManager.getExtensionEnabledCameraSelector(
                cameraProvider,
                cameraSelector,
                ExtensionMode.BOKEH
            )

            // Bind image capture and preview use cases with the extension enabled camera selector.
            val imageCapture = ImageCapture.Builder().build()
            val preview = Preview.Builder().build()
            cameraProvider.bindToLifecycle(
                lifecycleOwner,
                bokehCameraSelector,
                imageCapture,
                preview
            )
        }
    }
}

Java

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

void onCreate() {
    // Create a camera provider
    ProcessCameraProvider cameraProvider = ... // Get the provider instance

    // Call the getInstance function to retrieve a ListenableFuture object
    ListenableFuture future = ExtensionsManager.getInstance(lifecycleOwner);

    // Obtain the ExtensionsManager instance from the returned ListenableFuture object
    future.addListener(() -> {
        try {
            ExtensionsManager extensionsManager = future.get();

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

            // Query if extension is available.
            if (extensionsManager
                .isExtensionAvailable(cameraProvider, cameraSelector, ExtensionMode.BOKEH)) {
                // Unbind all use cases before enabling different extension modes.
                cameraProvider.unbindAll();

                // Retrieve extension enabled camera selector
                CameraSelector bokehCameraSelector = extensionsManager
                    .getExtensionEnabledCameraSelector(cameraProvider, cameraSelector, ExtensionMode.BOKEH);

                // Bind image capture and preview use cases with the extension enabled camera selector.
                ImageCapture imageCapture = new ImageCapture.Builder().build();
                Preview preview = new Preview.Builder().build();
                cameraProvider.bindToLifecycle(lifecycleOwner, bokehCameraSelector, imageCapture, preview);
            }
        } catch (ExecutionException | InterruptedException e) {
            // This should not happen unless the future is cancelled or the thread is interrupted by
            // applications.
        }
    }, ContextCompact.getMainExecutor(context));
}

Inhabilita el efecto

Para inhabilitar las extensiones de proveedor, desvincula todos los casos de uso y vuelve a vincular los de captura de imagen 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 de 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.1.0-alpha08"
  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:1.0.0-alpha28"
    ...
}

Kotlin

dependencies {
  val camerax_version = "1.1.0-alpha08"
  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:1.0.0-alpha28")
    ...
}

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 heredadas 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

  • Comienza a usar CameraX
  • Muestra de código

  • App de muestra de CameraX oficial