一、场景
安卓应用需要集成扫码功能
二、解决方案
从网上了解到的方法大部分都是集成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开源使用方法,作者也提供了引用库和简单的使用方法,亲测可行。