Android MLKit 仅在屏幕中央扫描二维码

标签 android firebase firebase-mlkit

我实现了 firebase MLKit 来扫描 QRCode,它正在扫描,但它正在扫描屏幕上的所有 QRcode。 我只需要扫描中心捕获的 QRCode(中心有箭头 ImageView),我该怎么做?

我尝试在 Analisys 函数上裁剪(在 analysisUseCase?.setAnalyzer 内)

imageProxy.cropRect()

我尝试在 processImageProxy 函数上裁剪。 但是没有成功,我认为我不能用这个裁剪

class QrcodeScanner(
        private val onQrCapture: Barcode.() -> Unit,
        private val onFailure: Throwable.() -> Unit,
        private val lifecycleOwner: LifecycleOwner,
        private val context: Context,
        private val previewView: PreviewView
) {

    private var cameraSelector: CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()
    private var cameraProvider: ProcessCameraProvider? = null
    private var previewUseCase: Preview? = null
    private var analysisUseCase: ImageAnalysis? = null

    fun startCamera() {
        val cameraProviderFuture =
                ProcessCameraProvider.getInstance(context)
        cameraProviderFuture.addListener(
                {
                    runCatching {
                        val provider = cameraProviderFuture.get()
                        cameraProvider = provider
                        startPreview()
                        startAnalysis()
                    }.onFailure {
                        onFailure(it)
                    }
                },
                ContextCompat.getMainExecutor(context)
        )
    }

    private fun startPreview() {
        if (previewUseCase != null) {
            cameraProvider?.unbind(previewUseCase)
        }

        previewUseCase = Preview.Builder()
                .setTargetRotation(previewView.display.rotation)
                .build()
        previewUseCase?.setSurfaceProvider(previewView.surfaceProvider)

        runCatching {
            cameraProvider?.bindToLifecycle(lifecycleOwner,
                    cameraSelector,
                    previewUseCase
            )
        }.onFailure {
            onFailure(it)
        }
    }

    private fun startAnalysis() {
        val options = BarcodeScannerOptions.Builder()
             .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
             .build()
        val barcodeScanner: BarcodeScanner = BarcodeScanning.getClient(options)

        if (cameraProvider == null) {
            return
        }
        if (analysisUseCase != null) {
            cameraProvider?.unbind(analysisUseCase)
        }

        analysisUseCase = ImageAnalysis.Builder()
                .setTargetRotation(previewView.display.rotation)
                .build()

        val cameraExecutor = Executors.newSingleThreadExecutor()

        analysisUseCase?.setAnalyzer(cameraExecutor, ImageAnalysis.Analyzer { imageProxy ->
            processImageProxy(barcodeScanner, imageProxy)
        })

        runCatching {
            cameraProvider?.bindToLifecycle(lifecycleOwner,
                    cameraSelector,
                    analysisUseCase
            )
        }.onFailure {
            onFailure(it)
        }

    }

    @SuppressLint("UnsafeExperimentalUsageError")
    private fun processImageProxy(
            barcodeScanner: BarcodeScanner,
            imageProxy: ImageProxy
    ) {
        runCatching {
            val img = imageProxy.image
            if (img != null) {
                val inputImage =
                        InputImage.fromMediaImage(img, imageProxy.imageInfo.rotationDegrees)

                barcodeScanner.process(inputImage)
                        .addOnSuccessListener { barcodes ->
                            barcodes.forEach {
                                onQrCapture(it)
                            }
                        }
                        .addOnFailureListener {
                            onFailure(it)
                        }.addOnCompleteListener {
                            imageProxy.close()
                        }
            } else {
                throw Exception("Falha ao processar a imagem")
            }
        }.onFailure {
            onFailure(it)
        }

    }

}

最佳答案

imageProxy.cropRect() 只在图片中放置元数据,不做裁剪操作。对于静态图像,您可以将其转换为位图并进行裁剪。更好的方法是在所有返回的条码都带有检测到的条码边界框时过滤掉结果。

在 MLKit 中,我们添加了对图像裁剪的支持。

关于Android MLKit 仅在屏幕中央扫描二维码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65746303/

相关文章:

java - oncreate Application 类中的 IllegalStateException

android - 在 ListView 滚动问题中更新单个项目 View

ios - 在 Firebase 中检索特定值

firebase-mlkit - 如何使用 Firebase/ML Kit 识别和计数对象

android - CameraX 在 Android 上用于 MLKit 文本识别的最佳用法

java - 编写提醒应用程序无法创建新对象

android - 使用 Gradle/Android Studio 为 Android 构建独立的静态库

firebase - firebase init后选择了错误的firebase数据库如何在原始数据库中切换

android - 在 Firemonkey 中实现 Firebase 消息传递

ios - 适用于 iOS 的 Firebase ML 套件 : "Unable to convert data to a string using the detected encoding" error when using local model