周末试用下Android手机的二维码扫描软件,扫描了下火车票、名片等等,觉得非常不错很有意思的。当然Java也可以实现这些,现在就分享下如何简单用Java实现二维码中QRCode的编码和解码(可以手机扫描验证)。
涉及到的一些主要类库,方便大家下载:
- 编码 lib:Qrcode_swetake.jar (官网介绍 — http://www.swetake.com/qr/index-e.html)
- 解码 lib:qrcode.jar (官网介绍 — http://sourceforge.jp/projects/qrcode/)
QRcode的详细介绍可参考:http://www.qrcode.com/en
后来发现一个更好的条形码和二维码的开源软件(ZXing),详见:条形码/二维码之开源利器ZXing图文介绍
【一】、编码:
QRCodeEncoderHandler.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
|
package
michael
.
qrcode
;
import
java
.
awt
.
Color
;
import
java
.
awt
.
Graphics2D
;
import
java
.
awt
.
image
.
BufferedImage
;
import
java
.
io
.
File
;
import
javax
.
imageio
.
ImageIO
;
import
com
.
swetake
.
util
.
Qrcode
;
/**
* 二维码生成器
* @blog http://www.micmiu.com
* @author Michael
*/
public
class
QRCodeEncoderHandler
{
/**
* 生成二维码(QRCode)图片
* @param content
* @param imgPath
*/
public
void
encoderQRCode
(
String
content
,
String
imgPath
)
{
try
{
Qrcode
qrcodeHandler
=
new
Qrcode
(
)
;
qrcodeHandler
.
setQrcodeErrorCorrect
(
'M'
)
;
qrcodeHandler
.
setQrcodeEncodeMode
(
'B'
)
;
qrcodeHandler
.
setQrcodeVersion
(
7
)
;
System
.
out
.
println
(
content
)
;
byte
[
]
contentBytes
=
content
.
getBytes
(
"gb2312"
)
;
BufferedImage
bufImg
=
new
BufferedImage
(
140
,
140
,
BufferedImage
.
TYPE_INT_RGB
)
;
Graphics2D
gs
=
bufImg
.
createGraphics
(
)
;
gs
.
setBackground
(
Color
.
WHITE
)
;
gs
.
clearRect
(
0
,
0
,
140
,
140
)
;
// 设定图像颜色 > BLACK
gs
.
setColor
(
Color
.
BLACK
)
;
// 设置偏移量 不设置可能导致解析出错
int
pixoff
=
2
;
// 输出内容 > 二维码
if
(
contentBytes
.
length
&
gt
;
0
&
amp
;
&
amp
;
contentBytes
.
length
&
lt
;
120
)
{
boolean
[
]
[
]
codeOut
=
qrcodeHandler
.
calQrcode
(
contentBytes
)
;
for
(
int
i
=
0
;
i
&
lt
;
codeOut
.
length
;
i
++
)
{
for
(
int
j
=
0
;
j
&
lt
;
codeOut
.
length
;
j
++
)
{
if
(
codeOut
[
j
]
[
i
]
)
{
gs
.
fillRect
(
j *
3
+
pixoff
,
i *
3
+
pixoff
,
3
,
3
)
;
}
}
}
}
else
{
System
.
err
.
println
(
"QRCode content bytes length = "
+
contentBytes
.
length
+
" not in [ 0,120 ]. "
)
;
}
gs
.
dispose
(
)
;
bufImg
.
flush
(
)
;
File
imgFile
=
new
File
(
imgPath
)
;
// 生成二维码QRCode图片
ImageIO
.
write
(
bufImg
,
"png"
,
imgFile
)
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
(
)
;
}
}
/**
* @param args the command line arguments
*/
public
static
void
main
(
String
[
]
args
)
{
String
imgPath
=
"D:/test/twocode/Michael_QRCode.png"
;
String
content
=
"Hello 大大、小小,welcome to QRCode!"
+
"\nMyblog [ http://sjsky.iteye.com ]"
+
"\nEMail [ sjsky007@gmail.com ]"
+
"\nTwitter [ @suncto ]"
;
QRCodeEncoderHandler
handler
=
new
QRCodeEncoderHandler
(
)
;
handler
.
encoderQRCode
(
content
,
imgPath
)
;
System
.
out
.
println
(
"encoder QRcode success"
)
;
}
}
|
运行后生成的二维码图片如下:
此时就可用手机的二维码扫描软件(本人用的:android 快拍二维码 )来测试下,识别成功的截图如下:
喜欢的朋友可以下载后试一试,做一些名片或者自己喜欢的东西。当然Java也可以对二维码图片解码,具体看下面关于解码的内容。
ps:有关上述代码中对输出内容限制的解释:由于各个版本、各个纠错等级的不同,实际容量是不一样的,上述限制只是为了演示简单实现控制而已。
【二】、解码:
QRCodeDecoderHandler.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
|
package
michael
.
qrcode
;
import
java
.
awt
.
image
.
BufferedImage
;
import
java
.
io
.
File
;
import
java
.
io
.
IOException
;
import
javax
.
imageio
.
ImageIO
;
import
jp
.
sourceforge
.
qrcode
.
QRCodeDecoder
;
import
jp
.
sourceforge
.
qrcode
.
data
.
QRCodeImage
;
import
jp
.
sourceforge
.
qrcode
.
exception
.
DecodingFailedException
;
/**
* @blog http://www.micmiu.com
* @author Michael
*/
public
class
QRCodeDecoderHandler
{
/**
* 解码二维码
* @param imgPath
* @return String
*/
public
String
decoderQRCode
(
String
imgPath
)
{
// QRCode 二维码图片的文件
File
imageFile
=
new
File
(
imgPath
)
;
BufferedImage
bufImg
=
null
;
String
decodedData
=
null
;
try
{
bufImg
=
ImageIO
.
read
(
imageFile
)
;
QRCodeDecoder
decoder
=
new
QRCodeDecoder
(
)
;
decodedData
=
new
String
(
decoder
.
decode
(
new
J2SEImage
(
bufImg
)
)
)
;
// try {
// System.out.println(new String(decodedData.getBytes("gb2312"),
// "gb2312"));
// } catch (Exception e) {
// // TODO: handle exception
// }
}
catch
(
IOException
e
)
{
System
.
out
.
println
(
"Error: "
+
e
.
getMessage
(
)
)
;
e
.
printStackTrace
(
)
;
}
catch
(
DecodingFailedException
dfe
)
{
System
.
out
.
println
(
"Error: "
+
dfe
.
getMessage
(
)
)
;
dfe
.
printStackTrace
(
)
;
}
return
decodedData
;
}
/**
* @param args the command line arguments
*/
public
static
void
main
(
String
[
]
args
)
{
QRCodeDecoderHandler
handler
=
new
QRCodeDecoderHandler
(
)
;
String
imgPath
=
"d:/test/twocode/Michael_QRCode.png"
;
String
decoderContent
=
handler
.
decoderQRCode
(
imgPath
)
;
System
.
out
.
println
(
"解析结果如下:"
)
;
System
.
out
.
println
(
decoderContent
)
;
System
.
out
.
println
(
"========decoder success!!!"
)
;
}
class
J2SEImage
implements
QRCodeImage
{
BufferedImage
bufImg
;
public
J2SEImage
(
BufferedImage
bufImg
)
{
this
.
bufImg
=
bufImg
;
}
public
int
getWidth
(
)
{
return
bufImg
.
getWidth
(
)
;
}
public
int
getHeight
(
)
{
return
bufImg
.
getHeight
(
)
;
}
public
int
getPixel
(
int
x
,
int
y
)
{
return
bufImg
.
getRGB
(
x
,
y
)
;
}
}
}
|
运行结果如下(解码出的内容和之前输入的内容一致 ):
解析结果如下:
Hello 大大、小小,welcome to QRCode!
Myblog [ http://sjsky.iteye.com ]
EMail [ sjsky007@gmail.com ]
Twitter [ @suncto ]
========decoder success!!!