ZXing读写二维码,桌面和手机的不同用法

梦想与她 提交于 2019-11-30 06:50:00

虽然ZXing是用Java实现的Barcode开源库,但是并不代表桌面上实现的Barcode应用在手机上也可以直接使用。因为Android的Java接口有很多是不同的。这里分享下Java Barcode生成和读取的不同用法。

参考原文:How to Write and Read QR Code with ZXing in Java

作者:Desmond Shaw

翻译:yushulx

获取ZXing源码

之前ZXing是放在Google Code上的,现在已经全部移到了GitHub上。命令行获取:

git clone https://github.com/zxing/zxing

在工程中添加ZXing

工程中导入ZXing有两方方法:

  1. 把ZXing编译成jar包,导入到工程中使用。比如在Android Studio中可以新建一个module,把ZXing源码导入之后就可以build出一个jar包。

  2. 直接使用ZXing源码。在工程属性中选择Project Properties > Java Build Path > Source > Link Source。确定输入正确的folder名称,不然会出现大量的package错误。


ZXing源码解析

要生成二维码,需要用到Writer类。搜索implements Writer可以看到所有ZXing支持的Barcode Writer。

这里包含了所有的1D/2D条形码。ZXing支持的条形码类型可以查询BarcodeFormat.java

public enum BarcodeFormat {     /** Aztec 2D barcode format. */   AZTEC,     /** CODABAR 1D format. */   CODABAR,     /** Code 39 1D format. */   CODE_39,     /** Code 93 1D format. */   CODE_93,     /** Code 128 1D format. */   CODE_128,     /** Data Matrix 2D barcode format. */   DATA_MATRIX,     /** EAN-8 1D format. */   EAN_8,     /** EAN-13 1D format. */   EAN_13,     /** ITF (Interleaved Two of Five) 1D format. */   ITF,     /** MaxiCode 2D barcode format. */   MAXICODE,     /** PDF417 format. */   PDF_417,     /** QR Code 2D barcode format. */   QR_CODE,     /** RSS 14 */   RSS_14,     /** RSS EXPANDED */   RSS_EXPANDED,     /** UPC-A 1D format. */   UPC_A,     /** UPC-E 1D format. */   UPC_E,     /** UPC/EAN extension format. Not a stand-alone format. */   UPC_EAN_EXTENSION   }

MultiFormatWriter 这个类包涵了各种条形码生成器:

@Override   public BitMatrix encode(String contents,                           BarcodeFormat format,                           int width, int height,                           Map<EncodeHintType,?> hints) throws WriterException {       Writer writer;     switch (format) {       case EAN_8:         writer = new EAN8Writer();         break;       case EAN_13:         writer = new EAN13Writer();         break;       case UPC_A:         writer = new UPCAWriter();         break;       case QR_CODE:         writer = new QRCodeWriter();         break;       case CODE_39:         writer = new Code39Writer();         break;       case CODE_128:         writer = new Code128Writer();         break;       case ITF:         writer = new ITFWriter();         break;       case PDF_417:         writer = new PDF417Writer();         break;       case CODABAR:         writer = new CodaBarWriter();         break;       case DATA_MATRIX:         writer = new DataMatrixWriter();         break;       case AZTEC:         writer = new AztecWriter();         break;       default:         throw new IllegalArgumentException("No encoder available for format " + format);     }     return writer.encode(contents, format, width, height, hints);   }

同样的,可以搜索implements Reader看到对应的类:

使用MultiFormatReader可以简化代码。

Windows, Mac和Linux上二维码的生成和读取

使用Java创建桌面Barcode应用,需要用到BufferedImage来操作图像。

Java QRCode Writer

public static void writeQRCode() {     QRCodeWriter writer = new QRCodeWriter();     int width = 256, height = 256;     BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // create an empty image     int white = 255 << 16 | 255 << 8 | 255;     int black = 0;     try {         BitMatrix bitMatrix = writer.encode("http://www.codepool.biz/zxing-write-read-qrcode.html", BarcodeFormat.QR_CODE, width, height);         for (int i = 0; i < width; i++) {             for (int j = 0; j < height; j++) {                 image.setRGB(i, j, bitMatrix.get(i, j) ? black : white); // set pixel one by one             }         }           try {             ImageIO.write(image, "jpg", new File("dynamsoftbarcode.jpg")); // save QR image to disk         } catch (IOException e) {             // TODO Auto-generated catch block             e.printStackTrace();         }       } catch (WriterException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } }

Java QRCode Reader

在读取图像数据的时候,需要使用RGBLuminanceSource来封装数据RGB。

 public static String readQRCode(String fileName) {     File file = new File(fileName);     BufferedImage image = null;     BinaryBitmap bitmap = null;     Result result = null;       try {         image = ImageIO.read(file);         int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth());         RGBLuminanceSource source = new RGBLuminanceSource(image.getWidth(), image.getHeight(), pixels);         bitmap = new BinaryBitmap(new HybridBinarizer(source));     } catch (IOException e) {         // TODO Auto-generated catch block         e.printStackTrace();     }       if (bitmap == null)         return null;       QRCodeReader reader = new QRCodeReader();        try {         result = reader.decode(bitmap);         return result.getText();     } catch (NotFoundException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (ChecksumException e) {         // TODO Auto-generated catch block         e.printStackTrace();     } catch (FormatException e) {         // TODO Auto-generated catch block         e.printStackTrace();     }       return null; }

Android上二维码的生成和读取

在Android平台上,BufferedImage是不存在的。取而代之的是Bitmap。

Android QRCode Writer

QRCodeWriter writer = new QRCodeWriter(); try {     int width = mImageView.getWidth();     int height = mImageView.getHeight();     BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, width, height);     Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);     for (int i = 0; i < width; i++) {         for (int j = 0; j < height; j++) {             bitmap.setPixel(i, j, bitMatrix.get(i, j) ? Color.BLACK: Color.WHITE);         }     }     mImageView.setImageBitmap(bitmap); } catch (WriterException e) {     e.printStackTrace(); }

Android QRCode Reader

从camera预览进来的数据是NV21格式的,所以在封装数据的时候需要使用PlanarYUVLuminanceSource 

MultiFormatReader reader = new MultiFormatReader();             LuminanceSource source = new PlanarYUVLuminanceSource(yuvData, dataWidth, dataHeight, left, top, width, height, false); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; try {     result = reader.decode(bitmap);     if (result != null) {         mDialog.setTitle("Result");         mDialog.setMessage(result.getText());         mDialog.show();     } } catch (NotFoundException e) {     // TODO Auto-generated catch block     e.printStackTrace(); }


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!