Opções de configuração

Configure cada caso de uso do CameraX para controlar diferentes aspectos das operações do caso de uso.

Por exemplo, com o caso de uso de captura de imagem, é possível configurar a proporção desejada e um modo de flash. O código a seguir mostra um exemplo:

Kotlin

val imageCapture = ImageCapture.Builder()
    .setFlashMode(...)
    .setTargetAspectRatio(...)
    .build()

Java

ImageCapture imageCapture =
    new ImageCapture.Builder()
        .setFlashMode(...)
        .setTargetAspectRatio(...)
        .build();

Além das opções de configuração, alguns casos de uso expõem APIs para mudar as configurações de forma dinâmica após a criação deles. Para informações sobre a configuração específica dos casos de uso individuais, consulte Implementar uma visualização, Analisar imagens e Captura de imagens.

Seleção automática

O CameraX fornece automaticamente uma funcionalidade específica do dispositivo em que seu app está sendo executado. Por exemplo, o CameraX determinará automaticamente a melhor resolução a ser usada se você não especificar nenhuma ou se a resolução especificada não for compatível. Tudo isso é processado pela biblioteca, eliminando a necessidade de criar um código específico para o dispositivo.

O objetivo do CameraX é inicializar uma sessão de câmera. Isso significa que o CameraX compromete a resolução e a proporção com base na capacidade do dispositivo. Isso pode acontecer pelos seguintes motivos:

  • O dispositivo não é compatível com a resolução solicitada.
  • O dispositivo tem problemas de compatibilidade, como dispositivos legados que precisam de determinadas resoluções para funcionar corretamente.
  • Em alguns dispositivos, determinados formatos estão disponíveis apenas em algumas proporções.
  • O dispositivo prefere um "mod16 mais próximo" para codificação JPEG ou de vídeo. Consulte SCALER_STREAM_CONFIGURATION_MAP para ver mais informações.

Embora o CameraX crie e gerencie a sessão, sempre verifique os tamanhos de imagem retornados na saída do caso de uso no seu código e faça as modificações necessárias.

Rotação

Por padrão, a rotação da câmera é definida para corresponder à rotação da tela padrão durante a criação do caso de uso. Nesse caso padrão, o CameraX produz saídas para permitir que o app corresponda facilmente ao que você espera da visualização. É possível mudar a rotação para um valor personalizado que seja compatível com dispositivos de várias telas transmitindo a orientação atual da tela ao configurar os objetos de caso de uso ou de forma dinâmica, depois de terem sido criados.

Seu app pode definir a rotação desejada usando as configurações. Em seguida, ele pode atualizar as configurações de rotação usando os métodos das APIs de caso de uso (como ImageAnalysis.setTargetRotation()), mesmo que o ciclo de vida esteja em execução. Você poderá usar isso quando o app estiver fixo no modo retrato para que nenhuma reconfiguração ocorra na rotação, mas o caso de uso de foto ou de análise precisará ser informado sobre a rotação atual do dispositivo. Por exemplo, os dados de rotação podem ser necessários para que os rostos fiquem na orientação correta para detecção facial ou as fotos sejam definidas como paisagem ou retrato.

Os dados das imagens capturadas podem ser armazenados sem informações de rotação. Os dados Exif contêm informações de rotação para que os aplicativos da galeria possam exibir a imagem na orientação correta depois de salvá-la.

Para exibir dados de visualização com a orientação correta, é possível usar a saída de metadados de Preview.PreviewOutput() para criar transformações.

A amostra a seguir traz um exemplo de como definir a rotação em um evento de orientação:

Kotlin

override fun onCreate() {
    val imageCapture = ImageCapture.Builder().build()

    val orientationEventListener = object : OrientationEventListener(this as Context) {
        override fun onOrientationChanged(orientation : Int) {
            // Monitors orientation values to determine the target rotation value
            val rotation : Int = when (orientation) {
                in 45..134 -> Surface.ROTATION_270
                in 135..224 -> Surface.ROTATION_180
                in 225..314 -> Surface.ROTATION_90
                else -> Surface.ROTATION_0
            }

            imageCapture.targetRotation = rotation
        }
    }
    orientationEventListener.enable()
}

Java

@Override
public void onCreate() {
    ImageCapture imageCapture = new ImageCapture.Builder().build();

    OrientationEventListener orientationEventListener = new OrientationEventListener((Context)this) {
       @Override
       public void onOrientationChanged(int orientation) {
           int rotation;

           // Monitors orientation values to determine the target rotation value
           if (orientation >= 45 && orientation < 135) {
               rotation = Surface.ROTATION_270;
           } else if (orientation >= 135 && orientation < 225) {
               rotation = Surface.ROTATION_180;
           } else if (orientation >= 225 && orientation < 315) {
               rotation = Surface.ROTATION_90;
           } else {
               rotation = Surface.ROTATION_0;
           }

           imageCapture.setTargetRotation(rotation);
       }
    };

    orientationEventListener.enable();
}

Com base na rotação definida, cada caso de uso fará a rotação dos dados da imagem diretamente ou fornecerá metadados de rotação aos consumidores dos dados de imagem não alterados.

  • Visualização: a saída de metadados é fornecida para que a rotação da resolução desejada seja conhecida usando Preview.getTargetRotation().
  • ImageAnalysis: a saída de metadados é fornecida para que as coordenadas do buffer de imagem sejam conhecidas em relação às coordenadas de exibição.
  • ImageCapture: os metadados, o buffer ou os metadados Exif da imagem serão alterados para observar a configuração de rotação. O valor alterado depende da implementação da HAL.

Resolução da câmera

Você pode permitir que o CameraX defina uma resolução de imagem com base em uma combinação dos recursos do dispositivo, nível de hardware compatível, caso de uso e proporção. Como alternativa, é possível definir uma resolução específica ou uma proporção específica em casos de uso compatíveis com essa configuração.

Resolução automática

O CameraX pode determinar automaticamente as melhores configurações de resolução com base nos casos de uso especificados em cameraProcessProvider.bindToLifecycle(). Sempre que possível, especifique todos os casos de uso necessários para serem executados simultaneamente em uma única sessão de uma única chamada bindToLifecycle(). O CameraX determinará resoluções com base no conjunto de casos de uso vinculados considerando o nível de hardware compatível e contabilizando a variação específica do dispositivo, em que um dispositivo pode exceder ou não cumprir as configurações de fluxo disponíveis. A intenção é permitir que o aplicativo seja executado em uma ampla variedade de dispositivos, minimizando os caminhos de código específicos do dispositivo.

A proporção padrão para os casos de uso de captura e análise de imagens é de 4:3.

Os casos de uso têm uma proporção configurável para permitir que o aplicativo especifique a proporção desejada com base no design da IU. A saída do CameraX será produzida para corresponder às proporções solicitadas tanto quanto possível. Se não houver uma correspondência exata com a resolução compatível, aquela que atender à maioria das condições será selecionada. Assim, o aplicativo determina como a câmera aparecerá no app, e o CameraX define as melhores configurações de resolução para diferentes dispositivos.

Por exemplo, um app pode:

  • especificar uma resolução desejada de 4:3 ou 16:9 para um caso de uso;
  • especificar uma resolução personalizada em que o CameraX tentará encontrar a correspondência mais próxima;
  • especificar uma proporção de corte para ImageCapture.

O CameraX escolherá automaticamente as resoluções de superfície internas do Camera2. A tabela a seguir mostra as resoluções:

Caso de uso Resolução de superfície interna Resolução de dados de saída
Visualização Proporção: a resolução que melhor se ajusta à configuração desejada. Resolução de superfície interna. Os metadados são fornecidos para permitir uma visualização para cortar, redimensionar e girar até chegar à proporção desejada.
Resolução padrão: a resolução de visualização mais alta ou a resolução preferencial por dispositivo mais alta correspondente à proporção acima.
Resolução máxima: o tamanho de visualização, referente ao melhor tamanho correspondente à resolução de tela do dispositivo ou a 1080 p (1920x1080), o que for menor.
Análise de imagem Proporção: a resolução que melhor se ajusta à configuração desejada. Resolução de superfície interna.
Resolução padrão: a configuração de resolução padrão é de 640 x 480. O ajuste da resolução e da proporção correspondente resultará em uma resolução mais compatível de menos de 1080p.
Resolução máxima: limitada pelo CameraX para 1080p. A resolução desejada é definida como 640 x 480 por padrão. Portanto, se você quiser uma resolução maior que 640 x 480, use setTargetResolution e setTargetAspectRatio para conseguir uma das resoluções compatíveis.
Captura de imagem Proporção: a proporção que melhor se adapta à configuração. Resolução de superfície interna.
Resolução padrão: a resolução mais alta disponível ou a resolução preferencial por dispositivo mais alta correspondente à proporção acima.
Resolução máxima: a resolução máxima de saída do dispositivo da câmera para formato JPEG de StreamConfigurationMap.getOutputSizes

Especificar uma resolução

Você pode definir resoluções específicas ao criar casos de uso com o método setTargetResolution(Size resolution), conforme mostrado na amostra de código a seguir:

Kotlin

val imageAnalysis = ImageAnalysis.Builder()
    .setTargetResolution(Size(1280, 720))
    .build()

Java

ImageAnalysis imageAnalysis =
  new ImageAnalysis.Builder()
    .setTargetResolution(new Size(1280, 720))
    .build();

Não é possível definir a proporção e a resolução desejadas no mesmo caso de uso. Fazer isso gerará uma IllegalArgumentException ao criar o objeto de configuração.

Expresse o Size da resolução no frame da coordenada depois de girar os tamanhos compatíveis pela rotação desejada. Por exemplo, um dispositivo com orientação natural de retrato na rotação natural pode especificar 480 x 640, enquanto o mesmo dispositivo, girado 90 graus e voltado para a orientação de paisagem, pode especificar 640 x 480.

A resolução máxima disponível para ImageAnalysis é de 1.080p. A limitação de 1.080p para ImageAnalysis considera fatores de desempenho e qualidade para que os usuários possam ter qualidade razoável e um fluxo de saída estável.

A resolução desejada tenta estabelecer um limite mínimo para a resolução da imagem. A resolução real da imagem será a disponível mais próxima que não seja menor que a resolução desejada, conforme determinado pela implementação da câmera. No entanto, se não houver uma resolução igual ou maior que a resolução desejada, será escolhida a resolução mais próxima disponível da desejada, ainda que menor. As resoluções com a mesma proporção do Size fornecido têm prioridade mais alta que as resoluções de proporções diferentes.

O CameraX aplicará a melhor resolução adequada com base nas solicitações. Se a principal necessidade for atender à proporção, especifique apenas setTargetAspectRatio, e o CameraX determinará uma resolução específica adequada, com base no dispositivo. Use setTargetResolution(Size resolution) se a necessidade principal do app for especificar uma resolução para tornar o processamento de imagens mais eficiente, por exemplo, em uma imagem de tamanho pequeno ou médio com base na capacidade de processamento do dispositivo.

Se o app exigir uma resolução exata, consulte a tabela em createCaptureSession para determinar quais resoluções máximas são compatíveis com cada nível de hardware. Para verificar as resoluções específicas compatíveis com o dispositivo atual, consulte StreamConfigurationMap.getOutputSizes(int).

Se o app estiver sendo executado no Android 10 ou mais recente, você poderá usar isSessionConfigurationSupported para verificar uma SessionConfiguration específica.

Controlar foco

A API CameraControl oferece recursos de "Toque para focar". Comece recebendo um objeto CameraControl, conforme mostrado no código a seguir:

Kotlin

val camera = processCameraProvider.bindToLifecycle(...)
val cameraControl = camera.getCameraControl()

Java

Camera camera = processCameraProvider.bindToLifecycle(...);
CameraControl cameraControl = camera.getCameraControl();

Use MeteringPointFactory, MeteringPoint, MeteringMode e FocusMeteringAction para executar o recurso "Toque para focar":

Kotlin

val factory = SurfaceOrientedMeteringPointFactory(width, height)
val point = factory.createPoint(x, y)
val action = FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
    .addPoint(point2, FocusMeteringAction.FLAG_AE) // could have many
    // auto calling cancelFocusAndMetering in 5 seconds
    .setAutoCancelDuration(5, TimeUnit.SECONDS)
    .build()

val future = cameraControl.startFocusAndMetering(action)
future.addListener( Runnable {
    val result = future.get()
    // process the result
} , executor)

Java

MeteringPointFactory factory = new SurfaceOrientedMeteringPointFactory(width, height);
MeteringPoint point = factory.createPoint(x, y);
FocusMeteringAction action = new FocusMeteringAction.Builder(point, FocusMeteringAction.FLAG_AF)
        .addPoint(point2, FocusMeteringAction.FLAG_AE) // could have many
        // auto calling cancelFocusAndMetering in 5 seconds
        .setAutoCancelDuration(5, TimeUnit.SECONDS)
        .build();

ListenableFuture future = cameraControl.startFocusAndMetering(action)
future.addListener( () -> {
    try {
        FocusMeteringResult result = future.get();
        // process the result
    } catch (Exception e) {
    }
} , executor);

Outros recursos

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

Codelab

  • Introdução ao CameraX (link em inglês)
  • Amostra de código

  • App de amostra oficial do CameraX (link em inglês)
  • Comunidade de desenvolvedores

    Grupo de discussão do CameraX do Android