API Extensions

O CameraX fornece a API Extensions para acessar os efeitos especiais abaixo:

  • Automático: ajusta automaticamente a imagem final com base no cenário.
  • Bokeh: deixa as pessoas em primeiro plano mais nítidas quando as fotos são tiradas no modo retrato.
  • Retoque facial: tonalização de pele e outros efeitos faciais ao tirar fotos.
  • HDR (High Dynamic Range): tira fotos com diferentes configurações de AE.
  • Modo noturno: tira ótimas fotos em ambientes com pouca luz, geralmente à noite.

que foram implementados em dispositivos Android (smartphones, tablets ou outros). Para que um dispositivo seja compatível com essas extensões de fornecedor, ele precisa atender a estes requisitos:

  • O efeito tem suporte a bibliotecas da ROM do dispositivo.
  • A biblioteca da ROM está instalada no dispositivo atual.
  • O dispositivo tem uma versão do sistema operacional exigida pela biblioteca.

Você pode ativar uma extensão de preferência: se ela for compatível e estiver fisicamente presente no dispositivo, será ativada. Caso contrário, ela será removida de forma eficiente.

Os fornecedores não precisam fornecer uma implementação para cada efeito e recurso. Qualquer recurso sem uma implementação fornecida pelo fornecedor é padronizado para a implementação do CameraX. A implementação padrão informa que o recurso não está disponível e pula a ativação.

Arquitetura de extensões

A imagem a seguir mostra a arquitetura das extensões com CameraX.

Figura 1. Arquitetura CameraX para extensões

As extensões são separadas do núcleo Camera2 do CameraX. No diagrama, as setas vermelhas indicam o fluxo de dados principal quando os usuários acionam um recurso com base em uma extensão, por exemplo, captura de imagens HDR.

Ativar um efeito para captura e visualização de imagem

Antes de usar a API de extensões, recupere uma instância do ExtensionsManager usando o método ExtensionsManager#getInstance(Context). Isso permitirá que você consulte as informações de disponibilidade da extensão. Em seguida, recupere um CameraSelector ativado para extensão. O modo de extensão será aplicado aos casos de uso de captura e visualização de imagens ao chamar o método bindToLifecycle() com a extensão CameraSelector ativada.

Para implementar a extensão para os casos de uso de captura e visualização de imagem, consulte o seguinte exemplo 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));
}

Desativar o efeito

Para desativar as extensões do fornecedor, desvincule todos os casos de uso e vincule novamente os casos de uso de captura e visualização de imagem com um seletor de câmera normal. Por exemplo, vincule-se novamente à câmera traseira usando CameraSelector.DEFAULT_BACK_CAMERA.

Dependências

A API Extensions do CameraX está implementada na biblioteca camera-extensions. As extensões dependem dos módulos principais do 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")
    ...
}

Remoção da API legada

Com a nova API Extensions lançada em 1.0.0-alpha26, a API Extensions legada lançada em agosto de 2019 foi descontinuada. A partir da versão 1.0.0-alpha28, a API Extensions legada foi removida da biblioteca. Os aplicativos que usam a nova API Extensions agora precisam usar um CameraSelector ativado da extensão e usá-lo para vincular os casos de uso.

Os aplicativos que usam a API Extensions legada precisam migrar para a nova API Extensions a fim de garantir a compatibilidade futura com as próximas versões do CameraX.

Outros recursos

Para saber mais sobre o CameraX, consulte os seguintes recursos.

Codelab

  • Introdução à CameraX
  • Exemplo de código

  • App de exemplo oficial do CameraX (link em inglês)