Zxing和QR Code生成和解析二維碼


本文是學習慕課網課程《Java生成二維碼》(http://www.imooc.com/learn/531)的筆記。

  一、二維碼的分類

    線性堆疊式二維碼、矩陣式二維碼、郵政碼。

  二、二維碼的優缺點

    優點:1. 高密度編碼,信息容量大;2.編碼范圍廣;3.容錯能力強;4.譯碼可靠性高;5.可引入加密措施;6.成本低,易制作,持久耐用。

    缺點:1.二維碼技術成為手機病毒、釣魚網站傳播的新渠道;2.信息容易泄露。

  三、三大國際標准

    1.PDF417:不支持中文;

    2.DM:專利未公開,需要支付專利費用;

    3.QR Code:專利公開,支持中文。

    其中,QR Code具有識讀速度快、數據密度大、占用空間小的優勢。

  四、糾錯能力

    L級:約可糾錯7%的數據碼字

    M級:約可糾錯15%的數據碼字

    Q級:約可糾錯25%的數據碼字

    H級:約可糾錯30%的數據碼字

  五、ZXing生成/讀取二維碼

    首先,下載ZXing源文件。下載地址:https://github.com/zxing/zxing/releases;

    再次,創建一個Java項目。將ZXing源文件中的core/src/main/java/com和javase/src/main/java/com兩個文件復制到項目中,編譯成jar文件;

    最后,在以后的開發中就可以使用該jar文件。

    ZXing生成二維碼的代碼如下:

 1 import java.io.File;
 2 import java.nio.file.Path;
 3 import java.util.HashMap;
 4 
 5 import com.google.zxing.BarcodeFormat;
 6 import com.google.zxing.EncodeHintType;
 7 import com.google.zxing.MultiFormatWriter;
 8 import com.google.zxing.WriterException;
 9 import com.google.zxing.client.j2se.MatrixToImageWriter;
10 import com.google.zxing.common.BitMatrix;
11 import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
12 
13 //生成二維碼
14 public class CreateQRCode {
15 
16     public static void main(String[] args) {
17         int width = 300;    //二維碼寬度
18         int height = 300;    //二維碼高度
19         String format = "png";         //二維碼圖片格式
20         String content = "www.baidu.com";    //二維碼內容
21         
22         //定義二維碼參數
23         HashMap hints = new HashMap();
24         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //定義內容字符集的編碼
25         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);        //定義糾錯等級
26         hints.put(EncodeHintType.MARGIN, 2);    //邊框空白
27         
28         try {
29             BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height);
30             
31             Path file = new File("E:/img.png").toPath();
32             
33             MatrixToImageWriter.writeToPath(bitMatrix, format, file);
34             //MatrixToImageWriter.writeToStream(bitMatrix, format, stream);
35         
36         } catch (Exception e) {
37             e.printStackTrace();
38         }
39     }
40 }

    

    ZXing讀取二維碼信息的代碼如下:

 1 import java.awt.image.BufferedImage;
 2 import java.io.File;
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 
 6 import javax.imageio.ImageIO;
 7 
 8 import com.google.zxing.Binarizer;
 9 import com.google.zxing.BinaryBitmap;
10 import com.google.zxing.EncodeHintType;
11 import com.google.zxing.LuminanceSource;
12 import com.google.zxing.MultiFormatReader;
13 import com.google.zxing.NotFoundException;
14 import com.google.zxing.Result;
15 import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
16 import com.google.zxing.common.BitArray;
17 import com.google.zxing.common.BitMatrix;
18 import com.google.zxing.common.HybridBinarizer;
19 
20 public class ReadQRCode {
21 
22     public static void main(String[] args) {
23         
24         try {
25             MultiFormatReader formatReader = new MultiFormatReader();
26             
27             File file = new File("E:/img.png");
28             
29             BufferedImage image = ImageIO.read(file);    //讀取此文件識別成一個圖片
30             
31             BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(image)));
32             
33             //定義二維碼參數
34             HashMap hints = new HashMap();
35             hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    //定義內容字符集的編碼
36 
37             
38             Result result = formatReader.decode(binaryBitmap,hints);
39             
40             System.out.println("解析結果:" + result.toString());    
41             System.out.println("二維碼格式類型:" + result.getBarcodeFormat());
42             System.out.println("二維碼文本內容:" + result.getText());
43         } catch (Exception e) {
44             e.printStackTrace();
45         }
46     }
47 }

    

  六、QRCode生成/讀取二維碼

    QRCode生成和讀取二維碼的jar是分開的,下載網址如下:

    QRCode生成二維碼網址:http://swetake.com/qrcode/index-e.html

    QRCode讀取二維碼網址:https://osdn.jp/projects/qrcode  (此網站無法下載到jar文件)

    (后面我在網上搜到一個包含生成和讀取二維碼功能的jar文件,下載路徑:https://files.cnblogs.com/files/bigroc/QRCode.zip)

    QRCode生成二維碼代碼如下:

 1 import java.awt.Color;
 2 import java.awt.Graphics2D;
 3 import java.awt.image.BufferedImage;
 4 import java.io.File;
 5 import java.io.IOException;
 6 import java.io.UnsupportedEncodingException;
 7 
 8 import javax.imageio.ImageIO;
 9 
10 import com.swetake.util.Qrcode;
11 
12 //生成二維碼
13 public class CreateQRCode {
14 
15     public static void main(String[] args) throws IOException {
16         
17         //計算二維碼圖片的高寬比
18         //API文檔規定計算圖片寬高的方式,v是版本號(1~40)
19         int v = 7;
20         int width = 67 + 12 * (v - 1);        //計算公式
21         int height = 67 + 12 * (v - 1);
22         
23         Qrcode x = new Qrcode();
24         
25         /**
26          * 糾錯等級分為
27          * level L : 最大 7% 的錯誤能夠被糾正;
28          * level M : 最大 15% 的錯誤能夠被糾正;
29          * level Q : 最大 25% 的錯誤能夠被糾正;
30          * level H : 最大 30% 的錯誤能夠被糾正;
31          */
32         x.setQrcodeErrorCorrect('L');    //設置糾錯等級
33         x.setQrcodeEncodeMode('B');    //N代表數字  A代表a-Z B代表其他字符
34         x.setQrcodeVersion(v);        //版本號(1~40)
35         String qrData = "http://www.baidu.com";    //內容信息
36         
37         //緩沖區
38         BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
39         
40         //繪圖
41         Graphics2D gs = bufferedImage.createGraphics();
42         
43         gs.setBackground(Color.WHITE);        //背景色
44         gs.setColor(Color.black);            
45         gs.clearRect(0, 0, width, height);    //清除畫板內容
46         
47         //偏移量 2或7
48         int pixoff = 2;
49         
50         /**
51          * 1.注意for循環里面的i,j的順序,
52          *   s[j][i]二維數組的j,i的順序要與這個方法中的 gs.fillRect(j*3+pixoff,i*3+pixoff, 3, 3);
53          *   順序匹配,否則會出現解析圖片是一串數字
54          * 2.注意此判斷if (d.length > 0 && d.length < 120)
55          *   是否會引起字符串長度大於120導致生成代碼不執行,二維碼空白
56          *   根據自己的字符串大小來設置此配置
57          */
58         //把要填充的內容轉化成字節數
59         byte[] d = qrData.getBytes("utf-8");    //漢字轉化格式
60         if (d.length > 0 && d.length < 120) {
61             boolean[][] s = x.calQrcode(d);
62 
63             for (int i = 0; i < s.length; i++) {
64                 for (int j = 0; j < s.length; j++) {
65                     if (s[j][i]) {
66                         //把d中的內容填充
67                         gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
68                     }
69                 }
70             }
71         }
72         
73         gs.dispose();            //結束寫入
74         bufferedImage.flush();    //結束buffered
75         ImageIO.write(bufferedImage, "png", new File("E:/img.png"));    //將圖片寫入到指定路徑下
76 
77     }
78 }

 

    QRCode解析二維碼代碼如下:

 1 import java.awt.image.BufferedImage;
 2 import java.io.File;
 3 import java.io.IOException;
 4 
 5 import javax.imageio.ImageIO;
 6 
 7 import jp.sourceforge.qrcode.QRCodeDecoder;
 8 
 9 public class ReadQRCode {
10 
11     public static void main(String[] args) throws IOException {
12         
13         //圖片路徑
14         File file = new File("E:/img.png");
15         //讀取圖片到緩沖區
16         BufferedImage bufferedImage = ImageIO.read(file);
17         //QRCode解碼器
18         QRCodeDecoder codeDecoder = new QRCodeDecoder();
19         
20         /**
21          *codeDecoder.decode(new MyQRCodeImage())
22          *這里需要實現QRCodeImage接口,MyQRCodeImage.java實現接口類
23          */
24         //通過解析二維碼獲得信息
25         String result = new String(codeDecoder.decode(new MyQRCodeImage(bufferedImage)), "utf-8");
26         System.out.println(result);
27     }
28 }

    

    MyQRCodeImage.java類實現QRCodeImage接口

 1 import java.awt.image.BufferedImage;
 2 
 3 import jp.sourceforge.qrcode.data.QRCodeImage;
 4 
 5 public class MyQRCodeImage implements QRCodeImage{
 6 
 7     BufferedImage bufferedImage;
 8     
 9     public MyQRCodeImage(BufferedImage bufferedImage) {
10         this.bufferedImage = bufferedImage;
11     }
12     
13     //
14     @Override
15     public int getWidth() {
16         return bufferedImage.getWidth();
17     }
18     
19     //
20     @Override
21     public int getHeight() {
22         return bufferedImage.getHeight();
23     }
24     
25     //顏色
26     @Override
27     public int getPixel(int i, int j) {
28         return bufferedImage.getRGB(i, j);
29     }
30 }

 

    七、注意事項

    jar包可放置在lib包下,還要設置此項目的builde path,選中項目,右擊,選擇Builde Path,點擊Configure Builde Path,在libraries下點擊Add Jars添加jar文件。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM