Java 生成二维码示例

背景

智能手机与平板等移动设备的普及,原本默默无闻的二维码迅速成为互联网应用的新宠。说到二维码,首先可以谈谈更为常见的条形码(bar code),比起二维码,条形码在日常生活中更为常见,并且早在十几年前就已经开始普及。大家最为熟悉的自然是图书馆中图书上的条形码标签。另外,日常的书籍,商品上大都会有条形码。在定义上条形码被称为“将宽度不等的多个黑条与空白,按照一定的编码规则排列,用以表达一组信息的标识符”。这个定义通俗的说,就是按照规则排列的黑色条形序列。与条形码在一维上表示信息不同,二维码是在二维平面上采用某种特定的几何形状按一定的规律分布的黑白相间的图形来记录信息。由于表达信息的维度增加,二维码能够存储的信息量也增大了。在条形码中只能包含数字和字母,二维码则可以包含汉字等其他内容。用途也更加广泛,诸如:支付,购票等。

码制

在上文的条形码与二维码定义中有一个比较模糊的词语,就是某种编码规则。这里所说的编码规则就是在编码学种通常所说的码制。不同的码制有不同的字符集,不同的字符宽度。当然,还有不同的校验功能以及其他诸如旋转不变,自动识别等方面的特点。常用的条形码包括: UPC(Unit Product Code), Code 3, Code 128等。二维码最为出名是QRCode, DataMatrix 以及 Aztec 等。当前微信,支付宝等用的都是 QRCode。

QRCode(Quick Response)是1994年由日本DENSO WAVE公司发明。QR 码使用四种标准化编码模式(数字,字母数字,字节(二进制)和汉字)来存储数据。QR码最常见于日本,为目前日本最流行的二维空间条码。QR码比较普通条码可以存储更多数据,也无需要像普通条码般在扫描时需要直线对准扫描仪。因此其应用范围已经扩展到包括产品跟踪,物品识别,文档管理,营销等方面。

QR码呈正方形,常见的是黑白两色。在3个角落,印有较小,像“回”字的正方图案。具体结构可见下图中说明:
QRCode

条形码与二维码生成器

得益于二维码的普及,以及开源社区的动力。目前二维码的生成器已经随处可见,作为程序猿,关心的是开源工具。目前Java语言 jar 包中的 BarCode4j, SwetakeQRCode, Zxing 生成二维码都十分方便,并且都提供了安卓,iOS,以及Web端的调用接口。由于 BarCode4j 二维码生成使用的是 dataMatrix码制,编写 Demo 略显繁琐,下面是用 SwetakeQRCode 与 Zxing 写的Demo。

SwetakeQRCode

SwetakeQRCode是由日本人编写的,由于不识日语,名字就不说了,下面的程序运行需要添加 SwetakeQRCode.jar文件。

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package club.icha;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.imageio.ImageIO;

import com.swetake.util.Qrcode;

public class QRCodeSwetake {

private static int UNIT_WIDTH = 15; //圖案寬度
private static int DEFAULT_WIDTH;


public static void createQRCode(String codeString) {
Qrcode qrcode = new Qrcode();
qrcode.setQrcodeErrorCorrect('M'); // L','M','Q','H'
qrcode.setQrcodeEncodeMode('B'); //"N","A" or other
qrcode.setQrcodeVersion(3); // 设置版本,范围: 0-20


byte[] buffer = null;
try {
buffer = codeString.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
boolean[][] bRect = qrcode.calQrcode(buffer); //计算二维码,结果用布尔数组表示,用于绘制
DEFAULT_WIDTH = bRect.length * UNIT_WIDTH;

// 生成二维码绘制背景图,并设置颜色
BufferedImage bufferedImage = new BufferedImage(DEFAULT_WIDTH, DEFAULT_WIDTH,BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2d = bufferedImage.createGraphics();
graphics2d.setBackground(Color.WHITE);
graphics2d.clearRect(0, 0, DEFAULT_WIDTH, DEFAULT_WIDTH);
graphics2d.setColor(Color.BLACK);

// 绘制二维码
if (buffer.length > 0 && buffer.length < 123) {
for (int i = 0; i < bRect.length; i++) {
for (int j = 0; j < bRect.length; j++) {
if (bRect[j][i]) {
graphics2d.fillRect(j * UNIT_WIDTH, i * UNIT_WIDTH,UNIT_WIDTH - 1, UNIT_WIDTH - 1);
}
}

}
}

graphics2d.dispose();
bufferedImage.flush();

//保存图片
String FilePath = "D:/QRCodebySwetake.png";
File f = new File(FilePath);

try {
ImageIO.write(bufferedImage, "png", f);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Congratulation!");
}

public static void main(String[] args) {
createQRCode("我本楚狂人,凤歌笑孔丘");
}
}

上面的程序生成图片如图:
QRCodebySwetake

Zxing

Zxing是由谷歌开发的二维码生成工具集,该工具集功能比较强大,还包含有二维码扫描功能,也是目前应用最为广泛的二维码开源工具。

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
package club.icha;

import java.io.File;
import java.util.Hashtable;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.ByteMatrix;

public class QRCodeZxing {

public static void main(String []args)throws Exception{
String text = "空山新雨后,天气晚来秋"; //二维码内容
int width = 200;
int height = 200;
String format = "png"; // 设置二维码格式
Hashtable<EncodeHintType, String> hints= new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
ByteMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height,hints);
File outputFile = new File("D:/QRCodebyZxing.png");
MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);
System.out.println("Congratulation!");
}
}

以上代码生成结果如图:
QRCodebyZxing

总结

二维码在目前看来是个比较有趣的话题,但二维码在信息存储量,安全等方面的问题也日益凸显。目前的彩色二维码是发展趋势之一。关于二维码的几个工具集,个人最喜欢的是Zxing, 文档齐全,功能强大。BarCode4j的文档写的特别烂, SwetakeQRCode 相对来说写代码时比较麻烦。另外还有一个收费的工具叫BarCode,没有试过。

[1] 二维码的概念与分类
[2] Java生成二维码的三个工具
[3] QR码
[4] 二维条码