Zxing core3.5.2自编码条码解码失败,抛出NotFoundException求助
问题描述
自行编码生成的二维码可被其他扫码APP识别,但通过BitMatrix与Bitmap转换为BinaryBitmap进行解码时,始终返回空结果,抛出如下异常:
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:558) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) Caused by: com.google.zxing.NotFoundException
相关代码
编码器代码
class BarcodeWriter: Writer { override fun encode( contents: String?, format: BarcodeFormat?, width: Int, height: Int ): BitMatrix { return MultiFormatWriter().encode(contents, format, width, height) } override fun encode( contents: String?, format: BarcodeFormat?, width: Int, height: Int, hints: MutableMap<EncodeHintType, *>? ): BitMatrix { return MultiFormatWriter().encode(contents, format, width, height, hints) } }
解码器代码
class BarcodeReader : Reader { override fun decode(image: BinaryBitmap?): Result { return MultiFormatReader().decode(image) } override fun decode(image: BinaryBitmap?, hints: MutableMap<DecodeHintType, *>?): Result { return MultiFormatReader().decode(image, hints) } override fun reset() { // } }
转换工具代码
fun bitMatrixToBmp(bitMatrix: BitMatrix, xColor: Int?, yColor: Int?): Bitmap { val height: Int = bitMatrix.height val width: Int = bitMatrix.width val bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565) for (x in 0 until width) { for (y in 0 until height) { bmp.setPixel(x, y, if (bitMatrix.get(x, y)) xColor?:Color.BLACK else yColor?:Color.WHITE) } } return bmp } fun bmpToBinaryBitmap(bitmap: Bitmap) : BinaryBitmap { val intArray = IntArray(bitmap.width * bitmap.height) val source = RGBLuminanceSource(bitmap.width, bitmap.height, intArray) return BinaryBitmap(HybridBinarizer(source)) } fun bitMatrixToBinary(bitMatrix: BitMatrix): BinaryBitmap { val intArray = IntArray(bitMatrix.width * bitMatrix.height) val source = RGBLuminanceSource(bitMatrix.width, bitMatrix.height, intArray) return BinaryBitmap(HybridBinarizer(source)) }
条码编码调用代码
val hints = hashMapOf( EncodeHintType.CHARACTER_SET to "utf-8" ) BarcodeWriter().encode( contents = "URL:${urlFormModel.url}", format = BarcodeFormat.QR_CODE, width = 100, height = 100, hints = hints )
条码解码调用代码
val decodeHints = hashMapOf( DecodeHintType.CHARACTER_SET to "utf-8", //DecodeHintType.PURE_BARCODE to true, //DecodeHintType.TRY_HARDER to true ) val result = BarcodeReader().decode(testBarcode.bitMatrix!!.toBinaryMap(), decodeHints)
解决方案
问题核心在于转换工具的代码存在数据填充遗漏,导致生成的BinaryBitmap不包含有效条码数据,同时解码调用存在方法名错误:
1. 修正转换工具代码
修复bmpToBinaryBitmap方法
该方法创建了intArray但未从Bitmap中读取像素数据,需补充像素读取逻辑:
fun bmpToBinaryBitmap(bitmap: Bitmap) : BinaryBitmap { val intArray = IntArray(bitmap.width * bitmap.height) // 从Bitmap中读取像素数据到数组 bitmap.getPixels(intArray, 0, bitmap.width, 0, 0, bitmap.width, bitmap.height) val source = RGBLuminanceSource(bitmap.width, bitmap.height, intArray) return BinaryBitmap(HybridBinarizer(source)) }
修复bitMatrixToBinary方法
该方法的intArray未填充BitMatrix的黑白像素数据,需遍历BitMatrix填充数组:
fun bitMatrixToBinary(bitMatrix: BitMatrix): BinaryBitmap { val width = bitMatrix.width val height = bitMatrix.height val intArray = IntArray(width * height) // 填充BitMatrix的黑白像素数据 for (y in 0 until height) { val offset = y * width for (x in 0 until width) { intArray[offset + x] = if (bitMatrix.get(x, y)) Color.BLACK else Color.WHITE } } val source = RGBLuminanceSource(width, height, intArray) return BinaryBitmap(HybridBinarizer(source)) }
2. 修正解码调用的方法名错误
解码调用中的toBinaryMap应为bitMatrixToBinary,同时优化解码参数提升识别率:
val decodeHints = hashMapOf( DecodeHintType.CHARACTER_SET to "utf-8", DecodeHintType.PURE_BARCODE to true, // 启用纯条码模式,跳过背景检测 DecodeHintType.TRY_HARDER to true, // 启用更复杂的识别逻辑 DecodeHintType.POSSIBLE_FORMATS to listOf(BarcodeFormat.QR_CODE) // 指定仅识别QR_CODE,缩小扫描范围 ) val result = BarcodeReader().decode(bitMatrixToBinary(testBarcode.bitMatrix!!), decodeHints)
3. 编码器优化(可选)
可以添加边距参数,避免条码边缘被截断,提升兼容性:
val hints = hashMapOf( EncodeHintType.CHARACTER_SET to "utf-8", EncodeHintType.MARGIN to 1 // 设置边距为1,符合QR码规范 ) BarcodeWriter().encode( contents = "URL:${urlFormModel.url}", format = BarcodeFormat.QR_CODE, width = 100, height = 100, hints = hints )
内容的提问来源于stack exchange,提问作者Crebain
相关产品推荐
相关产品推荐

