Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Opciones de configuración

Configura cada caso de uso de CameraX para controlar diferentes aspectos de sus operaciones.

Por ejemplo, con el caso de uso de captura de imágenes, puedes establecer una relación de aspecto y un modo de flash. El siguiente código muestra un ejemplo:

Kotlin

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

Java

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

Además de las opciones de configuración, algunos casos de uso exponen las API para alterar de forma dinámica la configuración después de que se crean. Para obtener información sobre la configuración específica de cada caso de uso, consulta Cómo implementar una vista previa, Cómo analizar imágenes y Captura de imágenes.

Selección automática

Automáticamente, CameraX proporciona funciones específicas para el dispositivo en el que se ejecuta tu app. Por ejemplo, CameraX determinará automáticamente la mejor resolución si no especificas una o si la que especificas no es compatible. Todo esto lo administra la biblioteca, lo que elimina la necesidad de escribir un código específico del dispositivo.

El objetivo de CameraX es inicializar con éxito una sesión de la cámara. Por lo tanto, CameraX ajusta la resolución y las relaciones de aspecto según la capacidad del dispositivo por los siguientes motivos:

  • El dispositivo no admite la resolución solicitada.
  • El dispositivo tiene problemas de compatibilidad, como los dispositivos heredados que requieren ciertas resoluciones para funcionar correctamente.
  • En algunos dispositivos, ciertos formatos solo están disponibles en determinadas relaciones de aspecto.
  • El dispositivo tiene preferencia por un "mod16 más cercano" para JPEG o codificación de video. Consulta SCALER_STREAM_CONFIGURATION_MAP para obtener más información.

Aunque CameraX crea y administra la sesión, siempre debes verificar en el código los tamaños de imagen que se muestran en los resultados del caso de uso y ajustarlos en consecuencia.

Rotación

De forma predeterminada, se configura la rotación de la cámara para que coincida con la rotación de la pantalla durante la creación del caso de uso. En este caso predeterminado, CameraX produce resultados que permiten que la app pueda lograr fácilmente lo que esperas obtener en la vista previa. Puedes cambiar la rotación a un valor personalizado a fin de admitir dispositivos de una amplia variedad de pantallas. Para ello, pasa la orientación de la pantalla del momento cuando se configura el caso de uso o hazlo de manera dinámica cuando ya se haya creado.

Tu app puede establecer la rotación objetivo con los parámetros de configuración. Luego, puede actualizar la configuración de rotación mediante los métodos de las API de casos de uso (como ImageAnalysis.setTargetRotation()), incluso mientras el ciclo de vida está en estado de ejecución. Esto es posible cuando la app está bloqueada en modo de retrato, por lo que no se produce ninguna reconfiguración de rotación, pero la foto o el caso de uso de análisis requieren que se tenga en cuenta la rotación del dispositivo de ese momento. Por ejemplo, el reconocimiento de rotación puede ser necesario para que los rostros estén orientados correctamente y se puedan detectar, o que las fotos estén configuradas en modo horizontal o vertical.

Los datos de las imágenes capturadas se pueden almacenar sin información de rotación. Los datos Exif contienen información de rotación para que las aplicaciones de galería puedan mostrar la imagen en la orientación correcta después de guardarla.

Para mostrar datos de vista previa con la orientación correcta, puedes usar el resultado de metadatos del objeto Preview.PreviewOutput() a fin de crear transformaciones.

En la siguiente muestra de código, se indica cómo configurar la rotación en un evento de orientación:

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

En función de la rotación, cada caso de uso rotará los datos de la imagen directamente o proporcionará los metadatos de rotación a los consumidores de los datos de la imagen no rotada.

  • Preview: Se proporciona un resultado de metadatos para que se conozca la rotación de la resolución objetivo con el elemento Preview.getTargetRotation().
  • ImageAnalysis: El resultado de los metadatos se proporciona para que se conozcan las coordenadas de búfer de la imagen en relación con las coordenadas de la pantalla.
  • ImageCapture: Se modificarán los metadatos de Exif de la imagen, el búfer o ambos para tener en cuenta la configuración de rotación. El valor modificado depende de la implementación de HAL.

Resolución de la cámara

Puedes permitir que CameraX configure la resolución de imagen según una combinación de funciones del dispositivo, el nivel de hardware compatible con el dispositivo, el caso de uso y la relación de aspecto proporcionada. Como alternativa, puedes establecer una resolución objetivo específica o una relación de aspecto específica en casos de uso que admitan esa configuración.

Resolución automática

CameraX puede determinar automáticamente la mejor configuración de resolución según los casos de uso especificados en el objeto cameraProcessProvider.bindToLifecycle(). Siempre que sea posible, especifica todos los casos de uso necesarios para ejecutar simultáneamente en una sola sesión, en una sola llamada al elemento bindToLifecycle(). CameraX determinará las resoluciones según el conjunto de casos de uso vinculados, teniendo cuenta el nivel de hardware compatible con el dispositivo y considerando la variación específica del dispositivo (en la que un dispositivo puede superar o no alcanzar las configuraciones de transmisión disponibles). El intent permite que la aplicación se ejecute en una amplia variedad de dispositivos y, al mismo tiempo, se minimicen las rutas de acceso de código específicas para cada dispositivo.

La relación de aspecto predeterminada para los casos de uso de análisis de imagen y captura de imagen es 4:3.

Los casos de uso tienen una relación de aspecto configurable para permitir que la aplicación especifique la relación de aspecto deseada según el diseño de la IU. El resultado de CameraX se producirá para que la relación de aspecto coincida lo más posible con lo solicitado, según lo que permita el dispositivo. Si no hubiera una concordancia exacta en la resolución admitida, se seleccionará la que cumpla con la mayor cantidad de condiciones posible. Entonces, la aplicación indicará cómo debería aparecer la cámara en la app, y CameraX determinará la mejor configuración de resolución de cámara para diferentes dispositivos.

Por ejemplo, una app puede realizar cualquiera de las siguientes acciones:

  • Especificar una resolución de objetivo de 4:3 o 16:9 para un caso práctico
  • Especificar una resolución personalizada, en la que CameraX intentará encontrar la coincidencia más cercana
  • Especificar una proporción de aspecto de recorte para ImageCapture

CameraX elegirá las resoluciones internas de superficie de Camera2 automáticamente. En la siguiente tabla, se muestran las resoluciones:

Caso práctico Resolución de superficie interna Resultado de resolución de datos
Vista previa Relación de aspecto: es la resolución que mejor se ajusta al objetivo de la configuración. Resolución de superficie interna Se proporcionan los metadatos con el objeto de permitir una vista a fin de recortar, ajustar y rotar la imagen para la relación de aspecto objetivo.
Resolución predeterminada: es la resolución de vista previa más alta o la resolución preferida por el dispositivo más alta que coincide con la relación de aspecto de arriba.
Resolución máxima: es el tamaño de la vista previa, que hace referencia a la mejor coincidencia de tamaño en relación con la resolución de pantalla del dispositivo, o a 1080p (1920 x 1080), el que sea menor.
Análisis de imágenes Relación de aspecto: es la resolución que mejor se ajusta al objetivo de la configuración. Resolución de superficie interna
Resolución predeterminada: la configuración de resolución objetivo predeterminada es 640 x 480. Ajustar la resolución objetivo y la relación de aspecto correspondiente dará como resultado una mejor resolución compatible por debajo de 1080p.
Resolución máxima: CameraX limita este valor a 1080p. La resolución objetivo se establece en 640 x 480 de forma predeterminada, por lo que si deseas una resolución superior a 640 x 480, debes usar los elementos setTargetResolution y setTargetAspectRatio para obtener la resolución más cercana a las que son compatibles.
Captura de imágenes Relación de aspecto: es la relación de aspecto que más se ajusta a la configuración. Resolución de superficie interna
Resolución predeterminada: es la resolución más alta disponible o la resolución más alta preferida por el dispositivo que coincide con la relación de aspecto de arriba.
Resolución máxima: la resolución máxima de salida del dispositivo de la cámara para el formato JPEG desde el objeto StreamConfigurationMap.getOutputSizes.

Especifica una resolución

Puedes establecer resoluciones específicas cuando compilas casos de uso con el método setTargetResolution(Size resolution), como se muestra en la siguiente muestra de código:

Kotlin

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

Java

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

No puedes establecer la relación de aspecto objetivo y la resolución objetivo en el mismo caso práctico, ya que se generará un elemento IllegalArgumentException cuando se compile el objeto de configuración.

Expresa la resolución Size en el marco de coordenadas después de rotar los tamaños compatibles según la rotación objetivo. Por ejemplo, un dispositivo con orientación natural vertical en rotación objetivo natural que solicita una imagen vertical puede especificar 480 x 640 y el mismo dispositivo con rotación a 90 grados y orientación horizontal puede especificar 640 x 480.

La resolución máxima disponible que puedes seleccionar para un objeto ImageAnalysis es 1080p. La limitación de 1080p para el objeto ImageAnalysis considera factores de rendimiento y calidad a fin de que los usuarios obtengan una calidad razonable y una transmisión fluida de salida.

La resolución objetivo intenta establecer un límite mínimo para la resolución de la imagen. La resolución de la imagen real será la resolución disponible más próxima al tamaño que no sea menor que la resolución objetivo, según lo determine la implementación de la Cámara. Sin embargo, si no existe una resolución que sea igual o mayor que la resolución objetivo, se elegirá la resolución disponible más próxima a la resolución objetivo. Las resoluciones con la misma relación de aspecto del elemento Size proporcionado tienen una prioridad más alta que las resoluciones de diferentes relaciones de aspecto.

CameraX aplicará la mejor resolución que se adecue a las solicitudes. Si la necesidad principal es satisfacer la relación de aspecto, especifica solo el objeto setTargetAspectRatio y CameraX determinará una resolución específica adecuada según el dispositivo. Si la necesidad principal de la app es especificar una resolución para que el procesamiento de imágenes sea más eficiente (por ejemplo, una imagen pequeña o mediana según la capacidad de procesamiento del dispositivo), usa el objeto setTargetResolution(Size resolution).

Si tu app requiere una resolución exacta, consulta la tabla en createCaptureSession para determinar qué resoluciones máximas admite cada nivel de hardware. Si necesitas verificar las resoluciones específicas compatibles con el dispositivo actual, consulta StreamConfigurationMap.getOutputSizes(int).

Si tu app se ejecuta en Android 10 o versiones posteriores, puedes usar el objeto isSessionConfigurationSupported para verificar un elemento SessionConfiguration específico.

Foco de control

La API de CameraControl ofrece la función de Presiona para enfocar. Comienza por obtener un objeto CameraControl, como se muestra en el siguiente código:

Kotlin

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

Java

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

Usa los objetos MeteringPointFactory, MeteringPoint, MeteringMode y FocusMeteringAction a fin de ejecutar la función de Presiona para enfocar:

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

Recursos adicionales

Para obtener más información acerca de CameraX, consulta los siguientes recursos adicionales.

Codelab

  • Cómo comenzar a usar CameraX
  • Muestra de código

  • App de muestra de CameraX oficial
  • Comunidad de desarrolladores

    Grupo de discusión sobre Android CameraX