参考网上文章,做如下实践。
implementation('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }
implementation 'com.google.zxing:core:3.3.0'
第一步:获取根据场景获取bitmap
1、通过url获取bitmap:
private void urlToBitmap(final String pic) {
new Thread() {
@Override
public void run() {
try {
URL url = new URL(pic);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if (conn.getResponseCode() == 200) {
InputStream inputStream = conn.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
//decodeImage(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
2、通过base64获取bitmap:
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
第二步:解析Bitmap,获取二维码对应的url。
public static Result handleQRCodeFormBitmap(Bitmap bitmap) {
Result result = null;
if (bitmap != null) {
// getSmallerBitmap 非常重要,图片太大会OOM,太小会找不到
bitmap = BitmapUtil.getSmallerBitmap(bitmap);
// 获取bitmap的宽高,像素矩阵
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
// 最新的库中,RGBLuminanceSource 的构造器参数不只是bitmap了
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
// 尝试解析此bitmap,!!注意!! 这个部分一定写到外层的try之中,因为只有在bitmap获取到之后才能解析。写外部可能会有异步的问题。(开始解析时bitmap为空)
try {
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);//花更多的时间用于寻找图上的编码,优化准确性,但不优化速度,Boolean类型
//加了hints解决了部分二维码解析出纯数字非url的问题
result = reader.decode(binaryBitmap, hints);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
}
return result;
}
//传入一个 bitmap,判断其大小是否 是 某一个 阙值(我在这里设置了1500000)的倍数。如果是其倍数,那么就等比缩小(也即是当 目前的bitmap大小为1500000的4倍的时候,那么宽,高各缩小2倍)
// 注意:阈值不能过小,图片压缩过小会导致识别不到二维码。
public static Bitmap getSmallerBitmap(Bitmap bitmap) {
int size = bitmap.getWidth() * bitmap.getHeight() / 1500000;//目前设计上最大的尺寸1000*1500,可根据自身产品情况做调整。
if (size <= 1) return bitmap; // 如果小于
else {
Matrix matrix = new Matrix();
matrix.postScale((float) (1 / Math.sqrt(size)), (float) (1 / Math.sqrt(size)));
Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return resizeBitmap;
}
}
第三步:result不为null,那么操作栏增加“识别图中二维码”的选项;用户点击该选项后,执行webview的访问操作:url=result.getText();
/**
* 判断是否为二维码
* param url 图片地址
* return
*/
private void decodeImage(final Bitmap bitmap) {
new Thread() {
@Override
public void run() {
result = handleQRCodeFormBitmap(bitmap);
Logger.d("result:" + result);
if (result == null) {
isQR = false;
} else {
isQR = true;
Logger.d("result text:" + result.getText());
}
if (isQR) {
handler.sendEmptyMessage(0);//通知用户操作ui修改
}
}
}.start();
}
本文详细介绍了如何使用ZXing库和Google ZXing核心库在Android应用中实现二维码的识别与解析,包括从URL和Base64字符串获取Bitmap,以及如何处理Bitmap以获取二维码对应的URL。
1749

被折叠的 条评论
为什么被折叠?



