Zxing识别图中二维码实践

参考网上文章,做如下实践。

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 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识别图中二维码实践)