Cuando agregues una vista previa a tu app, usa PreviewView, que es una View que se puede recortar, escalar y rotar para mostrarse correctamente.
La vista previa de la imagen se transmite a una superficie dentro de PreviewView cuando se activa la cámara.
Cómo usar PreviewView
La implementación de una vista previa de CameraX con PreviewView implica los siguientes pasos, que se explican en secciones posteriores:
- De manera opcional, configura un
CameraXConfig.Provider. - Agrega un elemento
PreviewViewa tu diseño. - Solicita un elemento
ProcessCameraProvider. - En la creación de
View, comprueba la presencia deProcessCameraProvider. - Selecciona una cámara y vincula el ciclo de vida y los casos de uso.
El uso de PreviewView tiene algunas limitaciones. Cuando usas PreviewView, no puedes hacer nada de lo siguiente:
- Crear un elemento
SurfaceTexturepara configurarTextureViewyPreview.SurfaceProvider - Recuperar el elemento
SurfaceTexturedeTextureViewy configurarlo enPreview.SurfaceProvider - Obtener el elemento
SurfacedeSurfaceViewy configurarlo enPreview.SurfaceProvider
Si ocurre algo de lo anterior, Preview deja de transmitir fotogramas a PreviewView.
Cómo agregar un elemento PreviewView a tu diseño
En el siguiente ejemplo, se muestra un PreviewView en un diseño:
<FrameLayout android:id="@+id/container"> <androidx.camera.view.PreviewView android:id="@+id/previewView" /> </FrameLayout>
Cómo solicitar un elemento CameraProvider
En el siguiente código, se muestra cómo solicitar un CameraProvider:
Kotlin
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture class MainActivity : AppCompatActivity() { private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider> override fun onCreate(savedInstanceState: Bundle?) { cameraProviderFuture = ProcessCameraProvider.getInstance(this) } }
Java
import androidx.camera.lifecycle.ProcessCameraProvider import com.google.common.util.concurrent.ListenableFuture public class MainActivity extends AppCompatActivity { private ListenableFuture<ProcessCameraProvider> cameraProviderFuture; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { cameraProviderFuture = ProcessCameraProvider.getInstance(this); } }
Comprueba la disponibilidad de CameraProvider
Después de solicitar un elemento CameraProvider, verifica que la inicialización se haya realizado correctamente cuando se cree la vista. El siguiente código muestra cómo hacer esto:
Kotlin
cameraProviderFuture.addListener(Runnable { val cameraProvider = cameraProviderFuture.get() bindPreview(cameraProvider) }, ContextCompat.getMainExecutor(this))
Java
cameraProviderFuture.addListener(() -> { try { ProcessCameraProvider cameraProvider = cameraProviderFuture.get(); bindPreview(cameraProvider); } catch (ExecutionException | InterruptedException e) { // No errors need to be handled for this Future. // This should never be reached. } }, ContextCompat.getMainExecutor(this));
Para ver un ejemplo de la función bindPreview que se usa en esta muestra, consulta el código proporcionado en la siguiente sección.
Selecciona una cámara y vincula el ciclo de vida y los casos de uso
Una vez que hayas creado y confirmado el CameraProvider, haz lo siguiente:
- Crea un elemento
Preview. - Especifica la opción de
LensFacingdeseada para la cámara. - Vincula la cámara y los casos de uso seleccionados al ciclo de vida.
- Conecta
PreviewaPreviewView.
En el siguiente código, se muestra un ejemplo:
Kotlin
fun bindPreview(cameraProvider : ProcessCameraProvider) { var preview : Preview = Preview.Builder() .build() var cameraSelector : CameraSelector = CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build() preview.setSurfaceProvider(previewView.getSurfaceProvider()) var camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, preview) }
Java
void bindPreview(@NonNull ProcessCameraProvider cameraProvider) { Preview preview = new Preview.Builder() .build(); CameraSelector cameraSelector = new CameraSelector.Builder() .requireLensFacing(CameraSelector.LENS_FACING_BACK) .build(); preview.setSurfaceProvider(previewView.getSurfaceProvider()); Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, preview); }
Ten en cuenta que bindToLifecycle() devuelve un objeto Camera. Si quieres obtener más información para controlar la salida de la cámara, como el zoom y la exposición, consulta Salida de cámara.
Ya terminaste de implementar la vista previa de la cámara. Compila tu app y confirma que la vista previa aparezca en ella y funcione como lo deseas.
Controles adicionales para PreviewView
CameraX PreviewView proporciona algunas API adicionales para configurar propiedades como las siguientes:
- El modo de implementación para renderizar transmisiones de vista previa.
- El tipo de escala de la imagen de vista previa.
Modo de implementación
PreviewView puede usar uno de los siguientes modos para renderizar una transmisión de vista previa en el View de destino:
PERFORMANCEes el modo predeterminado.PreviewViewusa unSurfaceViewpara mostrar la transmisión de video por Internet, pero recurre a unTextureViewen casos determinados.SurfaceViewposee una superficie de dibujo dedicada, que tiene más probabilidades de que el compositor de hardware interno lo implemente con una superposición de hardware, en especial cuando no hay otros elementos de la IU (botones "Me gusta") en la parte superior del video de vista previa. Al aplicar renderización con una superposición de hardware, los fotogramas de video evitan una ruta de GPU, lo que puede reducir el consumo de energía y la latencia de la plataforma.Modo
COMPATIBLE. En este modo,PreviewViewusa unTextureViewque, a diferencia deSurfaceView, no tiene una superficie de dibujo dedicada. Como resultado, el video se renderiza con una compaginación para que se pueda mostrar. Durante este paso adicional, la aplicación puede realizar otras tareas de procesamiento, como las de escalar y rotar videos sin restricciones.
Usa PreviewView.setImplementationMode() para seleccionar el modo de implementación adecuado para tu aplicación. Si el modo PERFORMANCE predeterminado no es adecuado para tu aplicación, en la siguiente muestra de código se muestra cómo configurar el modo COMPATIBLE:
Kotlin
// viewFinder is a PreviewView instance viewFinder.implementationMode = PreviewView.ImplementationMode.COMPATIBLE
Tipo de escala
Cuando la resolución de video de vista previa difiere de las dimensiones de tu PreviewView de destino, el contenido de video debe ajustarse a la vista recortando o usando formato letterbox (conservando la relación de aspecto original). PreviewView proporciona lo siguiente a ScaleTypes para este fin:
FIT_CENTER,FIT_STARTyFIT_ENDpara el formato letterbox. El contenido de video completo se ajusta (aumenta o reduce) al tamaño máximo posible que se puede mostrar en elPreviewViewde destino. Sin embargo, aunque el fotograma del video completo es visible, es posible que parte de la pantalla esté en blanco. Según cuál de estos tres tipos de escala elijas, el fotograma se alineará con el centro, el inicio o el final de la vista de destino.FILL_CENTER,FILL_STARTyFILL_ENDpara recorte. Si un video no coincide con la relación de aspecto dePreviewView, solo se verá una parte del contenido, pero llenará todo elPreviewView.
El tipo de escala predeterminado que usa CameraX es FILL_CENTER. Usa PreviewView.setScaleType() para establecer el tipo de escala más apropiado para tu aplicación. En la siguiente muestra de código, se configura el tipo de escala FIT_CENTER:
Kotlin
// viewFinder is a PreviewView instance viewFinder.scaleType = PreviewView.ScaleType.FIT_CENTER
El proceso para mostrar un video consta de los siguientes pasos:
- Escala el video:
- Para los tipos de escala
FIT_*, escala el video conmin(dst.width/src.width, dst.height/src.height). - Para los tipos de escala
FILL_*, escala el video conmax(dst.width/src.width, dst.height/src.height).
- Para los tipos de escala
- Alinea el video ajustado con el destino
PreviewView:- Para
FIT_CENTER/FILL_CENTER, alinea el centro del video ajustado a escala con elPreviewViewde destino. - Para
FIT_START/FILL_START, alinea el video ajustado y elPreviewViewde destino con respecto a la esquina superior izquierda de cada uno. - Para
FIT_END/FILL_END, alinea el video ajustado y el destinoPreviewViewcon respecto a la esquina inferior derecha de cada uno.
- Para
Por ejemplo, aquí hay un video de origen de 640 x 480 y un destino de PreviewView de 1920 x 1080:

En la siguiente imagen, se muestra el proceso de escalamiento de FIT_START, FIT_CENTER y FIT_END:

El proceso funciona de la siguiente manera:
- Escala el fotograma (manteniendo la relación de aspecto original) con
min(1920/640, 1080/480) = 2.25para obtener un fotograma intermedio de 1440 x 1080. - Alinea el fotograma de 1440 x 1080 con el
PreviewViewde 1920 x 1080.- Para
FIT_CENTER, alinea el fotograma con el centro de la ventanaPreviewView. Las columnas de 240 píxeles inicial y final dePreviewViewestán en blanco. - Para
FIT_START, alinea el fotograma con el inicio (esquina superior izquierda) de la ventanaPreviewView. Las columnas finales de 480 píxeles dePreviewViewestán en blanco. - Para
FIT_END, alinea el fotograma del video con el extremo (esquina inferior derecha) de la ventanaPreviewView. Las columnas iniciales de 480 píxeles dePreviewViewestán en blanco.
- Para
En la siguiente imagen, se muestra el proceso de escalamiento de FILL_START, FILL_CENTER y FILL_END:

El proceso funciona de la siguiente manera:
- Escala el fotograma con
max(1920/640, 1080/480) = 3para obtener un fotograma intermedio de 1920 x 1440 (que es más grande quePreviewView). - Recorta el fotograma de 1920 x 1440 para que se ajuste a la ventana
PreviewViewde 1920 x 1080.- Para
FILL_CENTER, recorta 1920 x 1080 del centro del video escalado de 1920 x 1440. Las 180 líneas de video superiores e inferiores no son visibles. - Para
FILL_START, recorta 1920 x 1080 desde el inicio del video ajustado a 1920 x 1440. Las 360 líneas de video inferiores no son visibles. - Para
FILL_END, recorta 1920 x 1080 desde el extremo del video escalado de 1920 x 1440. Las principales 360 líneas de video no son visibles.
- Para
Recursos adicionales
Para obtener más información sobre CameraX, consulta los siguientes recursos adicionales:
Codelab
Muestra de código