Fantástico ver como es el código de personalización de la camara 👍
Introducción a HMS Core
Pasos para el desarrollo de aplicaciones con Huawei
Debugging en la nube con Huawei
¿Qué es HMS Core?
Creación del proyecto en Android Studio
Creación de la aplicación en App Gallery Connect
Configuración de firma SHA-256
Configuración de APIs
Configuración de Android Studio y Gradle
Probando la sincronización de la aplicación
Autenticación con HMS Account Kit
Diseñando nuestra pantalla de login
Agregando los métodos de autenticación
Verificando la autenticación
Agregando el método de logout
Construyendo nuestra cámara de selfies con HMS ML Kit
Machine Learning con Huawei
Agregando los permisos para acceder a la cámara
Diseñando la pantalla personalizada de la cámara
Creando la capa de gráficos de la cámara
Creando el layout para nuestro rostro
Creando el layout del lente de la cámara
Creando nuestra actividad de cámara
Agregando nuestra cámara personalizada a la actividad
Agregando los métodos de verificación de rostro
Agregando la detección de rostro y sonrisa individual
Agregando la detección de rostro y sonrisa grupal
Tomar nuestra imagen y agregar un método de re-toma de foto
Guardar la foto en nuestra galeria
Aplicando notificaciones push con HMS Push kit
Crear el servicio de push notifications
Agregar el servicio de HMS Push kit
Verificar la conectividad de las notificaciones en App Gallery Connect
Conclusiones y consejos
Tips y solución de inconvenientes frecuentes
¿Qué más tiene Huawei?
You don't have access to this class
Keep learning! Join and start boosting your career
Get ready to take your camera application to the next level! In this guide, we are going to learn how to create a custom graphics layer using abstract classes and key functions. Our goal is to develop a camera that detects and frames our face for perfect selfies, and we will use machine learning tools like Lens Engine to achieve this.
An abstract class is a template for other classes that allows us to define methods to be implemented in child classes. Here, we are going to create an abstract class called BaseGraphic
, which will be the basis for customizing our camera using an object called GraphicOverlay
that we created in previous classes.
abstract class BaseGraphic(val overlay: GraphicOverlay) { abstract fun draw(canvas: Canvas)}
The draw
method is abstract, which means that every class that inherits from BaseGraphic
must implement it.
To scale and translate our graphics on the Android canvas, we will create functions for each of the axes:
Scaling allows us to adjust the size of our graphics in relation to the size of the canvas. We define functions to scale on the x and y axes:
fun scaleX(value: Float): Float { return value * overlay.widthScaleFactor // Scale in x}
fun scaleY(value: Float): Float { return value * overlay.heightScaleFactor // Scale in y}
Translation is necessary to center the graphics, especially when using the front camera. We implement this logic considering the specific properties of the LensEngine
.
fun translateX(value: Float): Float { return if (overlay.cameraFacing == LensEngine.FRONT_LENS) { overlay.width - scaleX(value) // Adjust x-axis for front camera } else { scaleX(value) // Scale x without translation }}
fun translateY(value: Float): Float { return scaleY(value) // Scale y}
To manage the graphics we will draw, we create a list in the GraphicOverlay
class and define functions to clear and add graphics. This ensures that the camera can update correctly.
private val graphics = synchronizedList<Graphic>()
fun clear() { graphics.clear() postInvalidate() // Update the overlay}
fun addGraphic(graphic: Graphic) { graphics.add(graphic)}
Finally, to draw a frame around the detected face, we implement the draw
function in GraphicOverlay
, making sure that the graphics are drawn only if the preview size is valid.
override fun onDraw(canvas: Canvas) { if (previewWidth != 0 && previewHeight != 0) { // Calculate scale factors val widthScaleFactor = canvas.width.toFloat() / previewWidth.toFloat() val heightScaleFactor = canvas.height.toFloat() / previewHeight.toFloat()
// Draw graphics for (graphic in graphics) { graphic.draw(canvas) } }}}
With this, we create a system that allows us to customize the way our camera interacts with the enhanced overlay. The LensEngine
implementation allows us to focus the face on the front camera to capture perfectly centered selfies. Don't stop here; keep learning about machine learning and other tools that can empower your camera app - the future of imaging technology is in your hands!
Contributions 3
Questions 1
Fantástico ver como es el código de personalización de la camara 👍
BaseGraphic
package com.sandoval.hselfiecamera.overlay
import android.graphics.Canvas
import com.huawei.hms.mlsdk.common.LensEngine
abstract class BaseGraphic(private val graphicOverlay: GraphicOverlay) {
abstract fun draw(canvas: Canvas?)
fun scaleX(x: Float): Float {
return x * graphicOverlay.widtScaleValue
}
fun scaleY(y: Float): Float {
return y * graphicOverlay.heightScaleValue
}
fun translateX(x: Float): Float {
return if (graphicOverlay.cameraFacing == LensEngine.FRONT_LENS) {
graphicOverlay.width - scaleX(x)
} else {
scaleX(x)
}
}
fun translateY(y: Float): Float {
return scaleY(y)
}
}
GraphicOverlay
package com.sandoval.hselfiecamera.overlay
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.View
import com.sandoval.hselfiecamera.camera.CameraConfiguration
class GraphicOverlay(
context: Context,
atts: AttributeSet?
) : View(context, atts) {
private val lock = Any()
private var previewWidth = 0
private var previewHeight = 0
var widtScaleValue = 1.0f
private set
var heightScaleValue = 1.0f
private set
var cameraFacing = CameraConfiguration.CAMERA_FACING_FRONT
private set
private val graphics: MutableList<BaseGraphic> = ArrayList()
fun addGraphic(graphic: BaseGraphic) {
synchronized(lock) { graphics.add(graphic) }
}
fun clear() {
synchronized(lock) { graphics.clear() }
this.postInvalidate()
}
fun setCameraInfo(width: Int, height: Int, facing: Int) {
synchronized(lock) {
previewWidth = width
previewHeight = height
cameraFacing = facing
}
this.postInvalidate()
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
synchronized(lock) {
if (previewWidth != 0 && previewHeight != 0) {
widtScaleValue =
width.toFloat() / previewWidth.toFloat()
heightScaleValue =
height.toFloat() / previewHeight.toFloat()
}
for (graphic in graphics) {
graphic.draw(canvas)
}
}
}
}
Want to see more contributions, questions and answers from the community?