To implement face detection expressed in this blog with Camera X and ML Kit, with custom overlay. That enables the shutter button only when the face is in the bounding box.
Expected result video and Starter source code with CameraX included
Following the Android camera X code labs, I could capture images and video. Though ML Kit bounding box implementation requires a Graphic Overlay.
class OverlayPosition(var x: Float, var y: Float, var r: Float)
class OverlayView @JvmOverloads constructor(
context: Context?,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
private val paint: Paint = Paint()
private var holePaint: Paint = Paint()
private var bitmap: Bitmap? = null
private var layer: Canvas? = null
private var border: Paint = Paint()
//position of hole
var holePosition: OverlayPosition = OverlayPosition(0.0f, 0.0f, 0.0f)
set(value) {
field = value
//redraw
this.invalidate()
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
if (bitmap == null) {
configureBitmap()
}
//draw background
layer?.drawRect(0.0f, 0.0f, width.toFloat(), height.toFloat(), paint)
//draw hole
layer?.drawCircle((width / 2).toFloat(), (height / 4).toFloat(), 400f, border)
layer?.drawCircle((width / 2).toFloat(), (height / 4).toFloat(), 400f, holePaint)
//draw bitmap
canvas.drawBitmap(bitmap!!, 0.0f, 0.0f, paint);
}
private fun configureBitmap() {
//create bitmap and layer
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
layer = Canvas(bitmap!!)
}
init {
//configure background color
val backgroundAlpha = 0.8
paint.color = ColorUtils.setAlphaComponent(context?.let {
ContextCompat.getColor(
it,
R.color.overlay
)
}!!, (255 * backgroundAlpha).toInt())
border.color = Color.parseColor("#FFFFFF")
border.strokeWidth = 30F
border.style = Paint.Style.STROKE
border.isAntiAlias = true
border.isDither = true
//configure hole color & mode
holePaint.color = ContextCompat.getColor(context, android.R.color.transparent)
holePaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
}
}