一、场景
安卓应用需要集成扫码功能
二、解决方案
从网上了解到的方法大部分都是集成zxing开源方案的,具体地址如下:
https://github.com/zxing/zxing
之前在网上找到一个案例集成,发现没有支持相册图片扫码功能,于是再次寻找方案,看到的大体思路如下:
1、界面增加跳转访问相册,获取图片uri;
2、对图片进行采样压缩处理;
3、将压缩后的bitmap图片流文件使用zxing 接口进行解码识别;
4、返回识别结果;
流程看起来很简单清晰,但是在调试过程中发现使用的方案总是识别不成功,调试发现代码抛出 com.google.zxing.NotFoundException 异常,在网上查了很多回答
大部分是说接口调用时的hint 设置问题如: https://github.com/zxing/zxing/issues/216
Hashtable<DecodeHintType, String> hints = new Hashtable<>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); //设置二维码内容的编码 scanBitmap = BitmapUtil.decodeUri(this, uri, 500, 500); RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e) { e.printStackTrace(); } catch (ChecksumException e) { e.printStackTrace(); } catch (FormatException e) { e.printStackTrace(); }
然而我这边将 hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE); 这个加上,以及将图片压缩的比例减小,即尽量还原图片,甚至直接使用原图还是不行。
在调试了无数遍之后,就知道还是要经历小马过河的场景,觉得使用的代码可能有问题。
后面继续寻找用了一个github上面关注较多的方案:https://github.com/yuzhiqiang1993/zxing
此方法刚开始也是失败的,后面又换了几张图片,竟然有成功的,于是大喜过望,开始研究其源码,发现其调用的解码接口类和之前的有所不同。
之前的:
QRCodeReader reader = new QRCodeReader(); try { return reader.decode(bitmap1, hints); } catch (NotFoundException e)
现在成功的:
MultiFormatReader multiFormatReader = new MultiFormatReader(); // 解码的参数 Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(2); // 可以解析的编码类型 Vector<BarcodeFormat> decodeFormats = new Vector<BarcodeFormat>(); // 扫描的类型 一维码和二维码 decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS); decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS); decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS); hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats); // 设置解析的字符编码格式为UTF8 // hints.put(DecodeHintType.CHARACTER_SET, "UTF8"); // 设置解析配置参数 multiFormatReader.setHints(hints); // 开始对图像资源解码 Result rawResult = null; try { rawResult = multiFormatReader.decodeWithState(new BinaryBitmap(new HybridBinarizer(new BitmapLuminanceSource(scanBitmap)))); Log.i("解析结果", rawResult.getText()); } catch (Exception e)
两者使用的reader 不同,不知道是不是因为后者支持的类型多了,所以成功的概率要大一些了,但是自己使用的图片都是二维码,按理跟这个没有区别,但是不管了,
能用就行,实力和时间不允许我深究。
所以如果要用比较完备的扫码功能的话,可以参考后者的github开源使用方法,作者也提供了引用库和简单的使用方法,亲测可行。