Personalización de Interfaz Gráfica para Cámara en Android

Clase 17 de 31Curso de Desarrollo de Aplicaciones con Huawei

Resumen

¿Cómo crear la base gráfica para personalizar una cámara?

¡Prepárate para llevar tu aplicación de cámara al siguiente nivel! En esta guía, vamos a aprender cómo crear una capa gráfica personalizada usando clases abstractas y funciones clave. Nuestro objetivo es desarrollar una cámara que detecte y encuadre nuestro rostro para selfies perfectas, y utilizaremos herramientas de machine learning como Lens Engine para lograrlo.

¿Qué es una clase abstracta y cómo puede ayudarnos en nuestra cámara?

Una clase abstracta es una plantilla para otras clases que nos permite definir métodos que deben implementarse en las clases hijas. Aquí, vamos a crear una clase abstracta llamada BaseGraphic, que será la base para personalizar nuestra cámara usando un objeto llamado GraphicOverlay que creamos en clases anteriores.

abstract class BaseGraphic(val overlay: GraphicOverlay) {
    abstract fun draw(canvas: Canvas)
}

El método draw es abstracto, lo que significa que cada clase que herede de BaseGraphic debe implementarlo.

¿Cómo escalamos y trasladamos gráficos en un lienzo?

Para escalar y trasladar nuestros gráficos en el lienzo de Android, crearemos funciones para cada uno de los ejes:

¿Cómo realizar el escalamiento en eje x e y?

El escalamiento nos permite ajustar el tamaño de nuestros gráficos en relación con el tamaño del lienzo. Definimos funciones para escalar en los ejes x e y:

fun scaleX(value: Float): Float {
    return value * overlay.widthScaleFactor // Escala en x
}

fun scaleY(value: Float): Float {
    return value * overlay.heightScaleFactor // Escala en y
}

¿Cómo se realiza la traslación en eje x e y?

La traslación es necesaria para centrar los gráficos, especialmente al usar la cámara frontal. Implementamos esta lógica considerando las propiedades específicas del LensEngine.

fun translateX(value: Float): Float {
    return if (overlay.cameraFacing == LensEngine.FRONT_LENS) {
        overlay.width - scaleX(value) // Ajusta el eje x para cámara frontal
    } else {
        scaleX(value) // Escala x sin traslación
    }
}

fun translateY(value: Float): Float {
    return scaleY(value) // Escala en y
}

¿Cómo manejamos los gráficos en el overlay?

Para gestionar los gráficos que dibujaremos, creamos una lista en la clase GraphicOverlay y definimos funciones para limpiar y añadir gráficos. Esto asegura que la cámara pueda actualizarse correctamente.

private val graphics = synchronizedList<Graphic>()

fun clear() {
    graphics.clear()
    postInvalidate() // Actualiza el overlay
}

fun addGraphic(graphic: Graphic) {
    graphics.add(graphic)
}

¿Cómo dibujamos el cuadro en la cámara?

Finalmente, para dibujar un cuadro alrededor del rostro detectado, implementamos la función draw en GraphicOverlay, asegurándonos de que los gráficos se dibujen solo si el tamaño del preview es válido.

override fun onDraw(canvas: Canvas) {
    if (previewWidth != 0 && previewHeight != 0) {
        // Calcular factores de escala
        val widthScaleFactor = canvas.width.toFloat() / previewWidth.toFloat()
        val heightScaleFactor = canvas.height.toFloat() / previewHeight.toFloat()

        // Dibujar gráficos
        for (graphic in graphics) {
            graphic.draw(canvas)
        }
    }
}

Con esto, creamos un sistema que nos permite personalizar la forma en que nuestra cámara interactúa con el mejorado overlay. La implementación del LensEngine permite focalizar el rostro en la cámara frontal para capturar selfies perfectamente centradas. No te detengas aquí; sigue aprender sobre machine learning y otras herramientas que pueden potenciar tu aplicación de cámara. ¡El futuro de la tecnología de imagen está en tus manos!