
为什么 ZXing 解码失败却没报错?
常见现象是调用 MultiFormatReader.decode() 后直接抛 NotFoundException,但图片明明有二维码——根本原因常是输入图像质量不达标。ZXing 默认只处理灰度、高对比度、边缘清晰的图像,手机拍的倾斜、反光、模糊图会静默失败。
- 务必先用
LuminanceSource子类包装图像:推荐BufferedImageLuminanceSource,别直接传byte[]或压缩过的 JPEG 流 - 解码前做简单预处理:裁剪掉大片空白边、转为灰度(
BufferedImage.TYPE_BYTE_GRAY)、用HybridBinarizer替代默认GlobalHistogramBinarizer - 别忽略
DecodeHintType:对模糊图加TRY_HARDER,对含中文的码必须设CHARACTER_SET为"UTF-8"
BufferedImage 怎么喂给 ZXing 才不丢信息?
很多人用 ImageIO.read(new File(...)) 直接读图,但 JPEG 解码可能引入色度抽样失真,PNG 透明通道会被忽略,导致二维码边缘断裂。关键不是“能读”,而是“读得准”。
- 强制转为无透明通道的灰度图:
new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY) - 用
Graphics2D绘制原图时开启抗锯齿关闭(RenderingHints.KEY_ANTIALIASING设为VALUE_ANTIALIAS_OFF),避免边缘柔化 - 若图中二维码占比小(
扫码结果乱码?检查这三处字符编码
中文二维码解出来是 “ ”,大概率不是 ZXing 的锅,而是字节流到字符串的转换断层。ZXing 内部用 String.getBytes() 回推编码,但你传的 hint 和实际生成时用的编码不一致就必然翻车。
- 生成端用了 UTF-8,解码端 hint 必须显式传
DecodeHintType.CHARACTER_SET→"UTF-8" - 如果生成方是微信/支付宝等黑盒服务,优先试
"GBK"和"UTF-8",别依赖默认值 - 拿到
Result.getText()后,立刻用result.getRawBytes()+ 指定 charset 构造字符串,比直接用 getText() 更可控
Android 上用 Camera2 实时扫码卡顿?
不是 ZXing 慢,是每帧都新建 MultiFormatReader + 全图 decode 导致 GC 频繁。ZXing 本身线程安全,但初始化成本高,且连续帧间内容高度重复。
立即学习“Java免费学习笔记(深入)”;
- 复用单例
MultiFormatReader,并在构造时传入固定HashMap<decodehinttype object></decodehinttype>,避免每次重算 hint - YUV_420_888 格式下,别转成
Bitmap再喂给 ZXing——用PlanarYUVLuminanceSource直接解析 NV21/YUV420 数据 - 加帧率控制:连续 3 帧未识别,跳过下一帧;识别成功后锁定 500ms 不再解,防止抖动重复触发










