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文件。

猜你喜欢

转载自www.cnblogs.com/silence-x/p/9483079.html