API Extensions

O CameraX fornece uma API Extensions para acessar os efeitos especiais abaixo que os fabricantes implementaram em vários dispositivos Android, como smartphones, tablets, entre outros

  • Automático: ajusta automaticamente a imagem final ao cenário. Por exemplo, a implementação da biblioteca do fornecedor pode realizar a detecção de ambiente com pouca luz e mudar para o modo pouca luz ou HDR para tirar uma foto. Além disso, a biblioteca pode aplicar automaticamente um modo de retoque facial ao tirar um retrato. O modo automático deixa a seleção do modo para a implementação da biblioteca do fornecedor.
  • Bokeh: o modo bokeh faz com que o objeto em primeiro plano fique mais nítido e desfoca o segundo plano da foto. Geralmente, ele é usado para tirar retratos parecidos com os que seriam produzidos por uma câmera com lentes grandes.
  • Retoque facial: retoca o tom de pele, a geometria e assim por diante ao capturar imagens estáticas.
  • HDR (High Dynamic Range): o modo HDR tira fotos com um intervalo maior de níveis de iluminação de cena visíveis na imagem final. Por exemplo, ao tirar a foto de um objeto em frente a uma janela bem iluminada, o objeto e a cena do outro lado da janela podem ficar visíveis com o uso do modo HDR. No modo normal, um dos elementos pode ficar com baixa exposição. Algumas desvantagens são que o modo HDR geralmente leva muito mais tempo para capturar uma única imagem, o usuário não tem controle e pode haver outros artefatos, dependendo do método HDR usado.
  • Noturno: captura as melhores fotos estáticas em situações com pouca luz, geralmente à noite.

Para que um dispositivo ofereça suporte a 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 da classe ExtensionsManager usando o método ExtensionsManager#getInstanceAsync(Context, CameraProvider). 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.getInstanceAsync(context, cameraProvider).await()

        // Select the camera
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

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

            // Retrieve extension enabled camera selector
            val bokehCameraSelector = extensionsManager.getExtensionEnabledCameraSelector(
                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 getInstanceAsync function to retrieve a ListenableFuture object
    ListenableFuture future =
            ExtensionsManager.getInstanceAsync(context, cameraProvider);

    // 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(cameraSelector, ExtensionMode.BOKEH)) {
                // Unbind all use cases before enabling different extension modes.
                cameraProvider.unbindAll();

                // Retrieve extension enabled camera selector
                CameraSelector bokehCameraSelector = extensionsManager
                    .getExtensionEnabledCameraSelector(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 na versão 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 recursos a seguir.

Codelab

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

  • Apps de exemplo do CameraX (link em inglês)
  • Outras referências

    Extensões do fornecedor CameraX

    Ferramenta de validação de extensões do fornecedor CameraX