第一步:准备依赖包:core-3.0.0.jar (扫二维码下载依赖包,哈哈)和一张准备放在二维码中间的图片
下载地址:http://central.maven.org/maven2/com/google/zxing/core/3.0.0/
第二步:打开Eclipse,新建一个web工程,起好工程名
在src中先键一个包,然后将下面两个java文件拷贝进src去
BufferedImageLuminanceSource.java
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package
com.simplelife;
import
java.awt.Graphics2D;
import
java.awt.geom.AffineTransform;
import
java.awt.image.BufferedImage;
import
com.google.zxing.LuminanceSource;
public
class
BufferedImageLuminanceSource
extends
LuminanceSource {
private
final
BufferedImage image;
private
final
int
left;
private
final
int
top;
public
BufferedImageLuminanceSource(BufferedImage image) {
this
(image,
0
,
0
, image.getWidth(), image.getHeight());
}
public
BufferedImageLuminanceSource(BufferedImage image,
int
left,
int
top,
int
width,
int
height) {
super
(width, height);
int
sourceWidth = image.getWidth();
int
sourceHeight = image.getHeight();
if
(left + width > sourceWidth || top + height > sourceHeight) {
throw
new
IllegalArgumentException(
"Crop rectangle does not fit within image data."
);
}
for
(
int
y = top; y < top + height; y++) {
for
(
int
x = left; x < left + width; x++) {
if
((image.getRGB(x, y) &
0xFF000000
) ==
0
) {
image.setRGB(x, y,
0xFFFFFFFF
);
// = white
}
}
}
this
.image =
new
BufferedImage(sourceWidth, sourceHeight,
BufferedImage.TYPE_BYTE_GRAY);
this
.image.getGraphics().drawImage(image,
0
,
0
,
null
);
this
.left = left;
this
.top = top;
}
public
byte
[] getRow(
int
y,
byte
[] row) {
if
(y <
0
|| y >= getHeight()) {
throw
new
IllegalArgumentException(
"Requested row is outside the image: "
+ y);
}
int
width = getWidth();
if
(row ==
null
|| row.length < width) {
row =
new
byte
[width];
}
image.getRaster().getDataElements(left, top + y, width,
1
, row);
return
row;
}
public
byte
[] getMatrix() {
int
width = getWidth();
int
height = getHeight();
int
area = width * height;
byte
[] matrix =
new
byte
[area];
image.getRaster().getDataElements(left, top, width, height, matrix);
return
matrix;
}
public
boolean
isCropSupported() {
return
true
;
}
public
LuminanceSource crop(
int
left,
int
top,
int
width,
int
height) {
return
new
BufferedImageLuminanceSource(image,
this
.left + left,
this
.top + top, width, height);
}
public
boolean
isRotateSupported() {
return
true
;
}
public
LuminanceSource rotateCounterClockwise() {
int
sourceWidth = image.getWidth();
int
sourceHeight = image.getHeight();
AffineTransform transform =
new
AffineTransform(
0.0
, -
1.0
,
1.0
,
0.0
,
0.0
, sourceWidth);
BufferedImage rotatedImage =
new
BufferedImage(sourceHeight,
sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g = rotatedImage.createGraphics();
g.drawImage(image, transform,
null
);
g.dispose();
int
width = getWidth();
return
new
BufferedImageLuminanceSource(rotatedImage, top,
sourceWidth - (left + width), getHeight(), width);
}
}
|
QRCodeUtil.java文件
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
package
com.simplelife;
import
java.awt.BasicStroke;
import
java.awt.Graphics;
import
java.awt.Graphics2D;
import
java.awt.Image;
import
java.awt.Shape;
import
java.awt.geom.RoundRectangle2D;
import
java.awt.image.BufferedImage;
import
java.io.File;
import
java.io.OutputStream;
import
java.util.Hashtable;
import
java.util.Random;
import
javax.imageio.ImageIO;
import
com.google.zxing.BarcodeFormat;
import
com.google.zxing.BinaryBitmap;
import
com.google.zxing.DecodeHintType;
import
com.google.zxing.EncodeHintType;
import
com.google.zxing.MultiFormatReader;
import
com.google.zxing.MultiFormatWriter;
import
com.google.zxing.Result;
import
com.google.zxing.common.BitMatrix;
import
com.google.zxing.common.HybridBinarizer;
import
com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
@SuppressWarnings
(
"all"
)
public
class
QRCodeUtil {
private
static
final
String CHARSET =
"utf-8"
;
private
static
final
String FORMAT_NAME =
"JPG"
;
// 二维码尺寸
private
static
final
int
QRCODE_SIZE =
300
;
// LOGO宽度
private
static
final
int
WIDTH =
60
;
// LOGO高度
private
static
final
int
HEIGHT =
60
;
private
static
BufferedImage createImage(String content, String imgPath,
boolean
needCompress)
throws
Exception {
Hashtable hints =
new
Hashtable();
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
hints.put(EncodeHintType.MARGIN,
1
);
BitMatrix bitMatrix =
new
MultiFormatWriter().encode(content,
BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
int
width = bitMatrix.getWidth();
int
height = bitMatrix.getHeight();
BufferedImage image =
new
BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for
(
int
x =
0
; x < width; x++) {
for
(
int
y =
0
; y < height; y++) {
image.setRGB(x, y, bitMatrix.get(x, y) ?
0xFF000000
:
0xFFFFFFFF
);
}
}
if
(imgPath ==
null
||
""
.equals(imgPath)) {
return
image;
}
// 插入图片
QRCodeUtil.insertImage(image, imgPath, needCompress);
return
image;
}
private
static
void
insertImage(BufferedImage source, String imgPath,
boolean
needCompress)
throws
Exception {
File file =
new
File(imgPath);
if
(!file.exists()) {
System.err.println(
""
+imgPath+
" 该文件不存在!"
);
return
;
}
Image src = ImageIO.read(
new
File(imgPath));
int
width = src.getWidth(
null
);
int
height = src.getHeight(
null
);
if
(needCompress) {
// 压缩LOGO
if
(width > WIDTH) {
width = WIDTH;
}
if
(height > HEIGHT) {
height = HEIGHT;
}
Image image = src.getScaledInstance(width, height,
Image.SCALE_SMOOTH);
BufferedImage tag =
new
BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(image,
0
,
0
,
null
);
// 绘制缩小后的图
g.dispose();
src = image;
}
// 插入LOGO
Graphics2D graph = source.createGraphics();
int
x = (QRCODE_SIZE - width) /
2
;
int
y = (QRCODE_SIZE - height) /
2
;
graph.drawImage(src, x, y, width, height,
null
);
Shape shape =
new
RoundRectangle2D.Float(x, y, width, width,
6
,
6
);
graph.setStroke(
new
BasicStroke(3f));
graph.draw(shape);
graph.dispose();
}
public
static
void
encode(String content, String imgPath, String destPath,
boolean
needCompress)
throws
Exception {
BufferedImage image = QRCodeUtil.createImage(content, imgPath,
needCompress);
mkdirs(destPath);
String file =
new
Random().nextInt(
99999999
)+
".jpg"
;
ImageIO.write(image, FORMAT_NAME,
new
File(destPath+
"/"
+file));
}
public
static
void
mkdirs(String destPath) {
File file =
new
File(destPath);
//当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
if
(!file.exists() && !file.isDirectory()) {
file.mkdirs();
}
}
public
static
void
encode(String content, String imgPath, String destPath)
throws
Exception {
QRCodeUtil.encode(content, imgPath, destPath,
false
);
}
public
static
void
encode(String content, String destPath,
boolean
needCompress)
throws
Exception {
QRCodeUtil.encode(content,
null
, destPath, needCompress);
}
public
static
void
encode(String content, String destPath)
throws
Exception {
QRCodeUtil.encode(content,
null
, destPath,
false
);
}
public
static
void
encode(String content, String imgPath,
OutputStream output,
boolean
needCompress)
throws
Exception {
BufferedImage image = QRCodeUtil.createImage(content, imgPath,
needCompress);
ImageIO.write(image, FORMAT_NAME, output);
}
public
static
void
encode(String content, OutputStream output)
throws
Exception {
QRCodeUtil.encode(content,
null
, output,
false
);
}
public
static
String decode(File file)
throws
Exception {
BufferedImage image;
image = ImageIO.read(file);
if
(image ==
null
) {
return
null
;
}
BufferedImageLuminanceSource source =
new
BufferedImageLuminanceSource(
image);
BinaryBitmap bitmap =
new
BinaryBitmap(
new
HybridBinarizer(source));
Result result;
Hashtable hints =
new
Hashtable();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result =
new
MultiFormatReader().decode(bitmap, hints);
String resultStr = result.getText();
return
resultStr;
}
public
static
String decode(String path)
throws
Exception {
return
QRCodeUtil.decode(
new
File(path));
}
public
static
void
main(String[] args)
throws
Exception {
String text =
"http://simplelife.blog.51cto.com/"
;
QRCodeUtil.encode(text,
"C:\\Users\\root\\Desktop\\123.jpg"
,
"C:\\Users\\root\\Desktop"
,
true
);
}
}
|
将两个java文件复制到工程之后,找到QRCodeUtil.java文件中的main方法,运行即可。
其中text指定的是扫描出二维码会得到的内容,text可以是文字或博客链接或者是文件下载链接等等……
运行生成博客的二维码:
额外知识:
二维码的基本原理,特别是四个角上分别代表什么?
简单地说,二维码就是使用深色模块(常见的是黑色)代表1,浅色模块(常见的是白色)代表0,按照一定的规则将这些深色模块和浅色模块排列而成的一种图形,用于表示01序列信息.
不同的二维码有不同的排列规则.
常 见的QR码的排列规则就是在一个矩形区域的三个角上要放置三个类似“回”字样的模块组合,用于表示二维码的三个顶点.根据这三个顶点可以计算出矩形的第四 个点.至于为什么选择“回”字样的图形作为顶点的标志,这是为了识别的时候快速定位而设计的.对于其他的二维码也有用垂直的两条折线表示二维码的顶点的.
二 维码识别的时候是通过对图像进行处理分析然后寻找这幅图像里面是否有二维码的,首先就需要按照二维码的排列规则寻找符合条件的定位图形,也就是要找到三个 类似“回”字的图形,如果找到了三个“回”字图形而且其位置基本在等腰直角三角形的三个顶点上,就说明这幅图像里面可能有一个二维码,然后就可以按照二维 码的排列规则进行取样,还原出一个01序列,再通过对这个01序列进行处理、纠错、验证以确定这个序列是否是一个完整、正确的二维码.
那么有了这 些基本的二维码概念和规则,就可以通过将计算机上的任意信息转化成01序列使用二维码表示了.这又牵涉到二维码里面的信息的转化规则,二维码里面一般称之 为编码规则,就是按照约定的方式将计算机里面的信息转化成01序列.在识别结束后再按照相反的顺序将这些01序列还原成计算机上的信息.
本文转自 兴趣e族 51CTO博客,原文链接:http://blog.51cto.com/simplelife/1744843