Creación del Motor de Lente para Selfie Cam en Android

Clase 19 de 31Curso de Desarrollo de Aplicaciones con Huawei

Contenido del curso

Introducción a HMS Core

Construyendo nuestra cámara de selfies con HMS ML Kit

Resumen

Construir una cámara de selfies con reconocimiento facial requiere un componente central que controle el lente del dispositivo: el Lens Engine. Este motor, proporcionado por Machine Learning de Huawei, es la pieza que conecta la superficie de la cámara con las capas de procesamiento gráfico. A continuación se explica paso a paso cómo implementarlo en Android con Kotlin.

¿Cómo se estructura la clase LensEnginePreview?

Dentro del paquete de cámara del proyecto se crea una nueva clase llamada LensEnginePreview [01:00]. Esta clase recibe como parámetros de constructor un contexto y un conjunto de atributos, y hereda de ViewGroup, la clase base de Android que agrupa vistas hijas.

Al heredar de ViewGroup es obligatorio implementar el método onLayout, que define cómo se posicionan los elementos visuales dentro del contenedor.

Las variables principales que se declaran son:

  • context: almacena el contexto de la actividad.
  • surfaceView: instancia de SurfaceView, la clase Android que gestiona la superficie donde se renderiza la imagen de la cámara [01:40].
  • startRequested: booleano que indica si ya se solicitó el arranque de la cámara.
  • surfaceAvailable: booleano que confirma si la superficie está lista para usarse.
  • lensEngine: objeto de tipo LensEngine del SDK de Huawei ML Kit, inicializado en nulo [02:15].
  • overlay: referencia a la clase GraphicOverlay creada en clases anteriores, también inicializada en nulo.

En el bloque init se establece startRequested y surfaceAvailable en false, se instancia el SurfaceView con el contexto y se agrega como vista hija mediante addView [02:50].

¿Qué funciones controlan el ciclo de vida de la cámara?

El ciclo de vida del lente se gestiona con tres funciones fundamentales.

¿Cómo funciona start?

La función start recibe el lensEngine y verifica que no sea nulo [03:20]. Si es nulo, significa que el motor ya no está disponible y se detiene el proceso. Cuando el motor existe, se asigna a la variable de clase, se marca startRequested = true y se invoca a startIfReady.

Una segunda sobrecarga de start acepta además el overlay, lo asigna y luego delega en la primera versión [04:10]. Esta separación permite inicializar la cámara con o sin capa gráfica.

¿Qué hacen stop y release?

La función stop verifica que el lensEngine no sea nulo y, de ser así, lo cierra con close() [03:40]. Esto detiene la captura de la cámara.

La función release libera completamente el recurso llamando a release() sobre el lensEngine y reasignándolo a nulo [05:00]. Se utiliza, por ejemplo, después de tomar una foto para devolver el control del hardware.

¿Cómo verifica startIfReady que la cámara esté lista?

Esta función es el corazón de la lógica de arranque [05:20]. Solo ejecuta el inicio real cuando se cumplen dos condiciones:

  • startRequested es true.
  • surfaceAvailable es true.

Cuando ambas se cumplen, se invoca lensEngine.run() pasándole el holder del SurfaceView. A continuación se obtienen las dimensiones de la pantalla mediante displayDimension del motor [05:50].

Se calculan dos valores de corrección con los métodos coarse (máximo) y atLeast (mínimo) del objeto Size de Huawei, aplicados al ancho y alto respectivamente [06:10]. Esto garantiza que la imagen se ajuste correctamente al tamaño del dispositivo.

Después se evalúa la orientación mediante context.resources.configuration.orientation. Si el dispositivo está en modo portrait, el overlay recibe la información de cámara con los valores mínimo y máximo invertidos respecto a landscape, junto con el lensType, que puede ser BACK_LENS o FRONT_LENS según la cámara activa [06:50]. Finalmente se limpia el overlay y se restablece startRequested a false.

¿Para qué sirve el SurfaceCallback?

Se crea una clase interna llamada SurfaceCallback que implementa SurfaceHolder.Callback [07:30]. Sus tres métodos controlan el estado de la superficie:

  • surfaceChanged: no requiere acción porque la superficie mantiene su forma.
  • surfaceDestroyed: establece surfaceAvailable = false.
  • surfaceCreated: marca surfaceAvailable = true, ejecuta startIfReady dentro de un bloque try-catch y captura cualquier IOException mostrando un mensaje de error si la cámara no puede arrancar [08:00].

Este callback es el enlace entre el sistema Android y la lógica del LensEngine, asegurando que la cámara solo se active cuando la superficie esté realmente disponible.

¿Has implementado Huawei ML Kit en alguno de tus proyectos? Comparte tu experiencia y las dificultades que encontraste.