如何在 CameraX TextureView 中绘制矩形

How to draw rectangle at CameraX TextureView

我写了下面的代码来绘制一个红色矩形,但显然它是错误的:(我没有得到任何错误,同时也没有绘制任何东西,我该如何解决它

    private fun updateTransform() {
        val matrix = Matrix()

        // Compute the center of the view finder
        val centerX = viewFinder.width / 2f
        val centerY = viewFinder.height / 2f

        // Correct preview output to account for display rotation
        val rotationDegrees = when(viewFinder.display.rotation) {
            Surface.ROTATION_0 -> 0
            Surface.ROTATION_90 -> 90
            Surface.ROTATION_180 -> 180
            Surface.ROTATION_270 -> 270
            else -> return
        }
        matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY)

        val bmp = Bitmap.createBitmap(1425, 1425, Bitmap.Config.ARGB_8888)
        val paint = Paint().apply {
            isAntiAlias = true
            style = Paint.Style.STROKE
            color = Color.RED
            strokeWidth = 10f
        }
        // x: {559, y: 1901}, height: 1425, width: 1425
        var canvas = Canvas(bmp)
        canvas.apply {
            drawRect(
                25.toFloat(), // faceRectangle.left,
                25.toFloat(), //faceRectangle.top,
                250.toFloat(),
                250.toFloat(),
                paint
            )
        }

        viewFinder.unlockCanvasAndPost(canvas)

        viewFinder.setTransform(matrix)

    }

我找到了解决此问题的方法,不确定这是否是唯一的方法,无论如何,我会 post 在这里以防将来对某人有帮助:

  • 解决方法是创建一个图像视图,与cameraX纹理视图具有相同的尺寸和位置(约束),作为覆盖,并在其上进行所有绘图,你只需要确保这个覆盖在纹理视图之上而不是在纹理视图之下,即在布局 xml 文件中跟随它。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextureView
        android:id="@+id/view_finder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:visibility="visible" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/pic_desc"
        android:visibility="visible" />

</androidx.constraintlayout.widget.ConstraintLayout>

绘图代码为:

lateinit var overlay: Bitmap
private fun startCamera() {
        val analyzerConfig = ImageAnalysisConfig.Builder().apply {
            setImageReaderMode(
                ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE)
        }.build()

        val analyzerUseCase = ImageAnalysis(analyzerConfig).apply {
            analyzer = ImageAnalysis.Analyzer { image, rotationDegrees ->
                val bitmap = view_finder.bitmap ?: return@Analyzer
                overlay = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)

                scope.launch(Dispatchers.Unconfined) {
                    val mat = Mat()
                    Utils.bitmapToMat(bitmap!!, mat)

                    val detectedFaces = FaceDetection.detectFaces(bitmap!!)

                   if (detectedFaces.toArray().isNotEmpty()) {
                       val paint = Paint().apply {
                           isAntiAlias = true
                           style = Paint.Style.STROKE
                           color = Color.RED
                           strokeWidth = 10f
                       }

                       for (rect in detectedFaces.toArray()) {
                           var canvas = Canvas(overlay)
                           canvas.drawRect(
                               rect.x.toFloat(), 
                               rect.y.toFloat(), 
                               rect.x.toFloat() + rect.width,
                               rect.y.toFloat() + rect.height,
                               paint
                           )
                           overlay?.let { Canvas(it) }?.apply {
                               canvas
                           }
                       }
                   }
                }

                runOnUiThread {
                    imageView.setImageBitmap(overlay)
                }
            }
        }
   CameraX.bindToLifecycle(this, preview, imageCapture, analyzerUseCase)
}

下面是我的应用程序的输出,现在显示了这张图: