You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google ML Kit条码扫描性能优化与反向条码识别问题咨询

识别性能优化方案

  • 复用扫描器实例:你当前代码每次调用analyze方法都会新建BarcodeScanner实例,该对象初始化开销极高,直接拖慢识别速度。将扫描器改为分析器的全局成员变量,只在类初始化时创建一次即可。
  • 修复ImageProxy关闭逻辑:你当前代码在异步scanner.process任务还没执行完成时,就直接在方法末尾调用了imageProxy.close(),导致扫描器拿到的帧资源已经被释放,只能等待后续新帧输入,拉长了识别耗时。需要将关闭逻辑移到异步任务的完成回调中,无论识别成功失败都要关闭帧资源,避免内存泄漏。
  • 给ImageAnalysis设置目标分辨率:你当前只给Preview和ImageCapture设置了720P的分辨率,ImageAnalysis默认会使用设备支持的最高分辨率,高分辨率帧的处理耗时是720P的数倍,给ImageAnalysis.Builder也加上setTargetResolution(Size(720, 1280))即可,识别Data Matrix码完全不需要更高的分辨率。
  • 移除不必要的相机用例:你同时绑定了预览、拍照、图像分析三个用例,多数中低端设备同时跑三个用例会大幅降低输出帧率,如果你不需要在扫码页面实时拍照,绑定用例时可以先去掉imageCapture,需要拍照时再动态绑定即可。

反向条码识别(反色处理)解决方案

你拿不到image.bitmapInternal或者image.byteBuffer是因为CameraX输出的mediaImage是YUV_420_888格式的多平面帧数据,本身没有单一ByteBuffer或者内置Bitmap属性,需要先将YUV帧转换为Bitmap再做反色处理,步骤如下:

  1. 引入YUV转Bitmap的工具方法,将ImageProxy实例转换为ARGB格式的Bitmap
  2. 对Bitmap做反色处理
  3. 将处理后的Bitmap转为InputImage喂给条码扫描器

修改后的分析器参考代码

private class BarCodeAnalyzer(private val listener: BarCodeListener) : ImageAnalysis.Analyzer {
    // 扫描器改成成员变量,只初始化一次
    private val options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(Barcode.FORMAT_DATA_MATRIX)
        .build()
    private val scanner = BarcodeScanning.getClient(options)

    @SuppressLint("UnsafeOptInUsageError")
    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image ?: run {
            imageProxy.close()
            return
        }
        // 先转Bitmap,YuvToRgbConverter可直接使用官方公开的工具类实现
        val yuvToRgbConverter = YuvToRgbConverter(context) // 自行传入可用的Context实例
        val bitmap = Bitmap.createBitmap(imageProxy.width, imageProxy.height, Bitmap.Config.ARGB_8888)
        yuvToRgbConverter.yuvToRgb(mediaImage, bitmap)
        
        // 反色处理(支持反向条码)
        val colorMatrix = ColorMatrix(floatArrayOf(
            -1f, 0f, 0f, 0f, 255f,
            0f, -1f, 0f, 0f, 255f,
            0f, 0f, -1f, 0f, 255f,
            0f, 0f, 0f, 1f, 0f
        ))
        val paint = Paint().apply {
            colorFilter = ColorMatrixColorFilter(colorMatrix)
        }
        val canvas = Canvas(bitmap)
        canvas.drawBitmap(bitmap, 0f, 0f, paint)

        // 转InputImage,注意要传入正确的旋转角度
        val inputImage = InputImage.fromBitmap(bitmap, imageProxy.imageInfo.rotationDegrees)

        scanner.process(inputImage)
            .addOnSuccessListener { barcodes ->
                barcodes.firstOrNull()?.rawValue?.let { barcode ->
                    Log.d(TAG, barcode)
                    listener(barcode)
                }
            }
            .addOnCompleteListener {
                // 无论成功失败都关闭帧资源
                imageProxy.close()
            }
    }
}

如果需要同时支持普通和反向条码,可以先对原图做识别,未识别到结果再用反色后的Bitmap做二次识别即可。

内容的提问来源于stack exchange,提问作者Bruce Wayne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 00:24:03