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

虽然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上。命令行获取:

?
1
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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 这个类包涵了各种条形码生成器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值