API Extensions do CameraX

O CameraX fornece uma API Extensions para acessar as extensões que os fabricantes implementaram em vários dispositivos Android. Para conferir uma lista dos modos de extensão com suporte, consulte Extensões de câmera.

Já para uma lista de dispositivos com suporte para extensões, consulte Dispositivos com suporte.

Arquitetura de extensões

A imagem a seguir mostra a arquitetura das extensões da câmera.

Figura 1. Arquitetura das extensões de câmera.

Um app da biblioteca CameraX pode usar extensões com a API Extensions dela. Essa API gerencia a consulta de extensões disponíveis, a configuração de uma sessão da câmera de extensão e a comunicação com a biblioteca OEM de extensões. Isso permite que o app use recursos como o modo noturno, HDR, automático, bokeh ou retoque facial.

Ativar uma extensão para captura e visualização de imagens

Antes de usar a API de extensões, extraia uma instância de 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 é 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

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));
}

Desativar uma extensão

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.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}")
    ...
}

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. Na versão 1.0.0-alpha28 e mais recentes, a API Extensions legada foi removida da biblioteca. Os aplicativos que usam a nova API Extensions agora precisam encontrar um CameraSelector ativado para extensão e usá-lo para vincular os casos de uso.

Os aplicativos que usam a API Extensions legada precisam migrar para a nova versão 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

    App de exemplo com extensões do CameraX

    Outras referências

    Extensões de fornecedor para CameraX

    Ferramenta de validação das extensões de fornecedor para CameraX