文章目录
一、二维条码/二维码(2-dimensional bar code)的概念
用某种特定的几何图形按一定规律再平面(二维方向上)分布的黑白相间的图形记录数据符号信息的图形。
二、二维码的发展历史
一维码:只能存储数字、字母,
二维码:可以存储汉字、数字、字母、图片等。
三、二维码的分类
线性堆叠式二维码: 建立在一维条码基础之上,按需要堆积成两行或多行
矩阵式二维码: 在一个矩形空间通过黑、白像素在矩阵中的不同分布进行编码(在矩阵相应元素位置上,用点的出现表示二进制“1”,点的不出现表示二进制的“0”)
邮政码: 通过不同长度的条进行编码,主要用于邮件编码
四、二维码的优缺点
二维码优点: 高密度编码,信息容量大;编码范围广;容错能力强;译码可靠性高;可引入加密措施;成本低,易制作,持久耐用。
缺点: 二维码技术成为手机病毒,钓鱼网站传播的新渠道;信息泄露。
五、QR Code
三大国际标准:
PDF147-- DM --QR code
QR code: 日本Denso公司1994年研发的一种矩阵二维码符号码,Quick Response Code
纠错能力: L级(7%)-M(15%)-Q(25%)-H(30%)
纠错能力越高,承载信息越少
JSP生成二维码方法: 第三方Jar如zxing\qrcodejar,javascript如jquery\qrcode.js
六、实例开发
1、zxing生成二维码
Zxing:
特点: 开源 java编写
下载后为源代码,需要自己打成jar包(包含core中的 com和javase中的com)
而我因为用的是IDEA所以用的依赖pom.xml:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
代码实现:
CreateQRCode.java:
//生成二维码
public class CreateQRCode {
public static void main(String[] args) {
int width = 300; //定义图片宽度
int height = 300; //定义图片高度
String format = "png"; //定义图片格式
String content = "https://blog.csdn.net/weixin_45537947"; //定义二维码内容
//定义二维码的参数
HashMap hashMap = new HashMap();
hashMap.put(EncodeHintType.CHARACTER_SET, "utf-8"); //设置编码
hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //设置容错等级,等级越高,容量越小
hashMap.put(EncodeHintType.MARGIN, 2); //设置边距
//生成二维码
try {
//生成矩阵
// 内容 格式 宽 高
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hashMap);
Path file = new File("F:/img.png").toPath(); //设置路径
MatrixToImageWriter.writeToPath(bitMatrix, format, file); //输出图像
} catch (Exception e) {
e.printStackTrace();
}
}
}
前往该路径,查看生成的二维码:
2、zxing进行二维码解析
代码演示:
public class ReadQRCode {
public static void main(String[] args) {
try {
/*
* MultiFormatReader 多格式读取
* */
MultiFormatReader formatReader = new MultiFormatReader();
File file = new File("F:/img.png");
//读取图片buffer中
BufferedImage bufferedImage = ImageIO.read(file);
/*
* BinaryBitmap 二进制位图
* HybridBinarizer 混合二值化器
* BufferedImageLuminanceSource 图像缓存区 亮度 资源
* */
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
//定义二维码参数
HashMap hashMap = new HashMap();
hashMap.put(EncodeHintType.CHARACTER_SET, "utf-8");//编码方式
//hashMap.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);//优化精度
//hashMap.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);//复杂模式,开启PURE_BARCODE模式
Result result = formatReader.decode(binaryBitmap,hashMap);
System.out.println("解析结果:"+result.toString());
System.out.println("二维码格式类型:"+result.getBarcodeFormat());//BarcodeFormat 条形码格式
System.out.println("二维码文本内容:"+result.getText());
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果:
解析过程中出现了这个报错:com.google.zxing.NotFoundException
所以我进行了debug发现扫描二维码时,二维码所有bit都是0,然后分析了一下,发现我在生成二维码的时候白色像素填充使用的是透明色,这样在显示的时候因为背景是白色,所以看上去和用手机扫都没有问题,但是自己代码识别的时候就会把透明色识别为黑色,这样就导致整个二维码图片全是黑色像素,所以zxing抛出com.google.zxing.NotFoundException异常。
所以只需要把上面代码演示的代码中把优化精度、复杂模式的注释取消就可以解决。
倘若你把内容设置成中文后出现一堆问号,则需要:
二维码内容写成中文之后,调用读取的类,读出来的是一堆问号的解决方式:
在读取类中该为BitMatrix bitMatrix=new MultiFormatWriter().encode(new String(content.getBytes(“UTF-8”),“ISO-8859-1”), BarcodeFormat.QR_CODE, width, height,hints);
在读取类和创建类中,将编码都设为"ISO-8859-1"就能读取中文了
hints.put(EncodeHintType.CHARACTER_SET, “ISO-8859-1”);
3、使用QR Code方式生成和解析二维码
生成: http://www.swetake.com/qrcode/index-e.html
读取: https://osdn.jp/projects/qrcode/
生成二维码,代码实现:(请先导入对应的包)
CreateQRCode.java:
public class CreateQRCode {
public static void main(String[] args) throws IOException {
QRCode x = new QRCode();
x.setQrCodeErrorCorrect('M'); //纠错等级
x.setQrcodeEncodeMode('B'); //N代表数字,A代表a-Z,B代表其它字符
x.setQrcodeVersion(7); //版本
String qrData = "https://blog.csdn.net/weixin_45537947";
int width = 67 + 12 * (7-1);
int height = 67 + 12 * (7-1);
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufferedImage.createGraphics();
gs.setBackground(Color.WHITE);
gs.setColor(Color.BLACK);
gs.clearRect(0, 0, width,height);
int pixoff = 2;//偏移量
byte[] d = qrData.getBytes("gb2312");
if (d.length > 0 && d.length < 120) {
boolean[][] booleans = x.calQrcode(d);
for (int i = 0;i < booleans.length; i++) {
for (int j = 0;j < booleans.length; j++) {
if (booleans[j][i]) {
gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
}
}
}
}
gs.dispose();
bufferedImage.flush();
ImageIO.write(bufferedImage, "png",new File("F://qrcode.png"));
}
}
4、jquery-qrcode生成二维码
jQuery-qrcode:
网址: https://github.com/jeromeetienne/jquery-qrcode
代码演示:
js的代码下载地址:
https://img.mukewang.com/down/5799a5440001040300000000.rar
qrcode.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>生成二维码</title>
<script type="text/javascript" src ="<%=request.getContextPath() %>/js/jquery.min.js"></script>
<script type="text/javascript" src ="<%=request.getContextPath() %>/js/jquery.qrcode.min.js"></script>
</head>
<body>
生成的二维码如下:<br>
<div id = "qrcode"></div>
<script type="text/javascript">
//二选一
jQuery('#qrcode').qrcode("https://blog.csdn.net/weixin_45537947");
// jQuery('#qrcode').qrcode({width: 250, height: 250,text: "https://blog.csdn.net/weixin_45537947"});
</script>
</body>
</html>
然后启动Tomcat, 访问:
关于二维码的简单学习就到这里ヾ(✿゚▽゚)ノ