热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Zxing和QRCode生成和解析二维码

本文是学习慕课网课程《Java生成二维码》(http:www.imooc.comlearn531)的笔记。一、二维码的分类线性堆叠式二维码、矩阵式二维码、邮政码。二

本文是学习慕课网课程《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 ) {
64                 for (int j = 0; 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文件。

 


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Java程序设计第4周学习总结及注释应用的开发笔记
    本文由编程笔记#小编为大家整理,主要介绍了201521123087《Java程序设计》第4周学习总结相关的知识,包括注释的应用和使用类的注释与方法的注释进行注释的方法,并在Eclipse中查看。摘要内容大约为150字,提供了一定的参考价值。 ... [详细]
author-avatar
bcz8936810
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有