概述
QR码的使用越来越多,可以在很多地方见着,比如火车票、推广产品上等,以下将介绍如何用Java生成QR码以及解码QR码。
1、涉及开源项目:
ZXing :一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。---用来解码QRcode
d-project:Kazuhiko Arase的个人项目(他具体是谁不清楚,日本的),提供丰富的配置参数,非常灵活---用来生成QR code
2、效果图:
生成QR code
解码QR code
3、使用d-project生成QRcdoe
1)将com.d_project.qrcode.jar引入工程
2)QRcodeAction代码:
public void generate(RequestContext rc)
002
throws UnsupportedEncodingException, IOException, ServletException {
003
//待转数据
004
String data = rc.param("data", "http://osctools.net/qr");
005
//输出图片类型
006
String output = rc.param("output", "image/jpeg");
007
008
int type = rc.param("type", 4);
009
if (type < 0 || 10 < type) {
010
return;
011
}
012
013
int margin = rc.param("margin", 10);
014
if (margin < 0 || 32 < margin) {
015
return;
016
}
017
018
int cellSize = rc.param("size", 4);
019
if (cellSize < 1 || 4 < cellSize) {
020
return;
021
}
022
023
int errorCorrectLevel = 0;
024
025
try {
026
errorCorrectLevel = parseErrorCorrectLevel(rc,
027
rc.param("error", "H"));
028
} catch (Exception e) {
029
return;
030
}
031
032
com.d_project.qrcode.QRCode qrcode = null;
033
try {
034
qrcode = getQRCode(data, type, errorCorrectLevel);
035
} catch (Exception e) {
036
return;
037
}
038
039
if ("image/jpeg".equals(output)) {
040
041
BufferedImage image = qrcode.createImage(cellSize, margin);
042
043
rc.response().setContentType("image/jpeg");
044
045
OutputStream out = new BufferedOutputStream(rc.response()
046
.getOutputStream());
047
048
try {
049
ImageIO.write(image, "jpeg", out);
050
} finally {
051
out.close();
052
}
053
054
} else if ("image/png".equals(output)) {
055
056
BufferedImage image = qrcode.createImage(cellSize, margin);
057
058
rc.response().setContentType("image/png");
059
060
OutputStream out = new BufferedOutputStream(rc.response()
061
.getOutputStream());
062
063
try {
064
ImageIO.write(image, "png", out);
065
} finally {
066
out.close();
067
}
068
069
} else if ("image/gif".equals(output)) {
070
071
GIFImage image = createGIFImage(qrcode, cellSize, margin);
072
073
rc.response().setContentType("image/gif");
074
075
OutputStream out = new BufferedOutputStream(rc.response()
076
.getOutputStream());
077
078
try {
079
image.write(out);
080
} finally {
081
out.close();
082
}
083
084
} else {
085
return;
086
}
087
088
}
089
090
private static int parseErrorCorrectLevel(RequestContext rc, String ecl) {
091
if ("L".equals(ecl)) {
092
return ErrorCorrectLevel.L;
093
} else if ("Q".equals(ecl)) {
094
return ErrorCorrectLevel.Q;
095
} else if ("M".equals(ecl)) {
096
return ErrorCorrectLevel.M;
097
} else if ("H".equals(ecl)) {
098
return ErrorCorrectLevel.H;
099
} else {
100
throw rc.error("qr_error_correct_error");
101
}
102
103
}
104
105
106
private static QRCode getQRCode(String text, int typeNumber,
107
int errorCorrectLevel) throws IllegalArgumentException {
108
if (typeNumber == 0) {
109
return QRCode.getMinimumQRCode(text, errorCorrectLevel);
110
} else {
111
QRCode qr = new QRCode();
112
qr.setTypeNumber(typeNumber);
113
qr.setErrorCorrectLevel(errorCorrectLevel);
114
qr.addData(text);
115
qr.make();
116
return qr;
117
}
118
}
119
120
private static GIFImage createGIFImage(QRCode qrcode, int cellSize,
121
int margin) throws IOException {
122
123
int imageSize = qrcode.getModuleCount() * cellSize + margin * 2;
124
125
GIFImage image = new GIFImage(imageSize, imageSize);
126
127
for (int y = 0; y < imageSize; y++) {
128
129
for (int x = 0; x < imageSize; x++) {
130
131
if (margin <= x && x < imageSize - margin && margin <= y
132
&& y < imageSize - margin) {
133
134
int col = (x - margin) / cellSize;
135
int row = (y - margin) / cellSize;
136
137
if (qrcode.isDark(row, col)) {
138
image.setPixel(x, y, 0);
139
} else {
140
image.setPixel(x, y, 1);
141
}
142
143
} else {
144
image.setPixel(x, y, 1);
145
}
146
}
147
}
148
149
return image;
150
}
3)前端页面:
<script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script>
002
003 <script type="text/javascript">
004
005
$(document).ready(function(){
006
007
$("#submit").click(function(){
008
009
var url = "/action/qrcode/generate?" + $("#qrcode_form").serialize();
010
011
$(".QRCodeDiv img").attr("src",url+"&"+new Date().getTime());
012
013
$("#gen_url").attr("href",url);
014
015
});
016
017
$("#zxing").popover({
018
019
'title':'条形码处理类库 ZXing',
020
021
'content':'ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。',
022
023
'placement':'bottom'
024
025
});
026
027
});
028
029 </script>
030
031 <div id="mainContent" class="wrapper">
032
033 <div class="toolName">在线生成二维码(QR码)-采用<a id="zxing" href="http://www.oschina.net/p/zxing">ZXing</a>与<a href="http://www.d-project.com/">d-project</a><a data-toggle="modal" href="#advice" style="float:right;text-decoration:none;"><span class="badge badge-important"><i class="icon-envelope icon-white"></i> Feedback</span></a></div>
034
035 <div class="toolUsing clearfix">
036
037
<div class="toolsTab
clearfix">
038
039
<ul class="nav nav-tabs">
040
041
<li class="active"><a href="/qr">转QR码</a></li>
042
043
<li ><a href="/qr?type=2">二维码解码</a></li>
044
045
</ul>
046
047
<div class="clear"></div>
048
049
</div>
050
051
<form id="qrcode_form" method="post" >
052
053
<div class="leftBar">
054
055
<div class="title">URL或其他文本:</div>
056
057
<textarea class="input-xlarge" name="data" onfocus="if(this.value=='http://osctools.net/qr'){this.value='';};this.select();" onblur="(this.value=='')?this.value='http://osctools.net/qr':this.value;">http://osctools.net/qr</textarea>
058
059
</div>
060
061
<div class="operateLR">
062
063
<div class="OptDetail span1">
064
065
<label>输出格式:</label>
066
067
<select name="output" class="span1">
068
069
<option value="image/gif" selected>GIF</option>
070
071
<option value="image/jpeg">JPEG</option>
072
073
<option value="image/png">PNG</option>
074
075
</select>
076
077
<label>纠错级别:</label>
078
079
<select name="error" class="span1">
080
081
<option value="L" selected>L 7%</option>
082
083
<option value="M">M 15%</option>
084
085
<option value="Q">Q 25%</option>
086
087
<option value="H">H 30%</option>
088
089
</select>
090
091
<label>类型:</label>
092
093
<select name="type" class="span1">
094
095
<option value="0">自动</option>
096
097
<option value="1">1</option>
098
099
<option value="2">2</option>
100
101
<option value="3">3</option>
102
103
<option value="4">4</option>
104
105
<option value="5">5</option>
106
107
<option value="6">6</option>
108
109
<option value="7">7</option>
110
111
<option value="8">8</option>
112
113
<option value="9">9</option>
114
115
<option value="10">10</option>
116
117
</select>
118
119
<label>边缘留白:</label>
120
121
<select name="margin" class="span1">
122
123
<option value="0">0</option>
124
125
<option value="1">1</option>
126
127
<option value="2">2</option>
128
129
<option value="3">3</option>
130
131
<option value="4">4</option>
132
133
<option value="5">5</option>
134
135
<option value="6">6</option>
136
137
<option value="7">7</option>
138
139
<option value="8">8</option>
140
141
<option value="9">9</option>
142
143
<option value="10">10</option>
144
145
<option value="11">11</option>
146
147
<option value="12">12</option>
148
149
<option value="13">13</option>
150
151
<option value="14">14</option>
152
153
<option value="15">15</option>
154
155
<option value="16">16</option>
156
157
<option value="17">17</option>
158
159
<option value="18">18</option>
160
161
<option value="19">19</option>
162
163
<option value="20">20</option>
164
165
<option value="21">21</option>
166
167
<option value="22">22</option>
168
169
<option value="23">23</option>
170
171
<option value="24">24</option>
172
173
<option value="25">25</option>
174
175
<option value="26">26</option>
176
177
<option value="27">27</option>
178
179
<option value="28">28</option>
180
181
<option value="29">29</option>
182
183
<option value="30">30</option>
184
185
<option value="31">31</option>
186
187
<option value="32">32</option>
188
189
</select>
190
191
<label>原胞大小:</label>
192
193
<select name="size" class="span1">
194
195
<option value="1"
>1</option>
196
197
<option value="2"
>2</option>
198
199
<option value="3"
>3</option>
200
201
<option value="4" selected >4</option>
202
203
</select>
204
205
<button class="btn btn-small btn-primary" id="submit" onclick="return false;">生成QR码</button>
</div>
206
207
</div>
208
209
<div class="rightBar">
210
211
<div class="title">QR码:</div>
212
213
<div class="QRCodeDiv">
214
215
<div class="QRWrapper">
216
217
<a id="gen_url" href="/action/qrcode/generate?size=4" target="_blank"><img src="/action/qrcode/generate?size=4"/></a>
218
219
</div>
220
221
</div>
222
223
</div>
224
225
</form>
226
227 </div>
228
229 </div>
4、使用ZXing解码QRcode
1)下载Zxing-2.0.zip
2)引入zxing-barcode_core.jar与zxing_barcode_j2se.jar到工程
3)QRcodeAction代码:
@PostMethod
002
@JSONOutputEnabled
003
public void decode(RequestContext rc) throws IOException {
004
//存在qrcode的网址
005
String url = rc.param("url", "");
006
//待解码的qrcdoe图像
007
File img = rc.file("qrcode");
008
if (StringUtils.isBlank(url) && img == null) {
009
throw rc.error("qr_upload_or_url_null");
010
}
011
012
List<Result> results = new ArrayList<Result>();
013
Config config = new Config();
014
Inputs inputs = new Inputs();
015
016
config.setHints(buildHints(config));
017
018
if (StringUtils.isNotBlank(url)) {
019
addArgumentToInputs(url, config, inputs);
020
}
021
if (img != null) {
022
inputs.addInput(img.getCanonicalPath());
023
}
024
while (true) {
025
String input = inputs.getNextInput();
026
if (input == null) {
027
break;
028
}
029
File inputFile = new File(input);
030
if (inputFile.exists()) {
031
try {
032
Result result = decode(inputFile.toURI(), config,rc);
033
results.add(result);
034
} catch (IOException e) {
035
}
036
} else {
037
try {
038
Result result = decode(new URI(input), config,rc);
039
results.add(result);
040
} catch (Exception e) {
041
}
042
}
043
}
044
rc.print(new Gson().toJson(results));
045
}
046
047
private Result decode(URI uri,Config config,RequestContext rc)
048
throws IOException {
049
Map<DecodeHintType, ?> hints = config.getHints();
050
BufferedImage image;
051
try {
052
image = ImageIO.read(uri.toURL());
053
} catch (IllegalArgumentException iae) {
054
throw rc.error("qr_resource_not_found");
055
}
056
if (image == null) {
057
throw rc.error("qr_could_not_load_image");
058
}
059
try {
060
LuminanceSource source = new BufferedImageLuminanceSource(image);
061
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
062
Result result = new MultiFormatReader().decode(bitmap, hints);
063
return result;
064
} catch (NotFoundException nfe) {
065
throw rc.error("qr_no_barcode_found");
066
}
067
}
068
069
private static Map<DecodeHintType, ?> buildHints(Config config) {
070
Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(
071
DecodeHintType.class);
072
Collection<BarcodeFormat> vector = new ArrayList<BarcodeFormat>(8);
073
vector.add(BarcodeFormat.UPC_A);
074
vector.add(BarcodeFormat.UPC_E);
075
vector.add(BarcodeFormat.EAN_13);
076
vector.add(BarcodeFormat.EAN_8);
077
vector.add(BarcodeFormat.RSS_14);
078
vector.add(BarcodeFormat.RSS_EXPANDED);
079
if (!config.isProductsOnly()) {
080
vector.add(BarcodeFormat.CODE_39);
081
vector.add(BarcodeFormat.CODE_93);
082
vector.add(BarcodeFormat.CODE_128);
083
vector.add(BarcodeFormat.ITF);
084
vector.add(BarcodeFormat.QR_CODE);
085
vector.add(BarcodeFormat.DATA_MATRIX);
086
vector.add(BarcodeFormat.AZTEC);
087
vector.add(BarcodeFormat.PDF_417);
088
vector.add(BarcodeFormat.CODABAR);
089
vector.add(BarcodeFormat.MAXICODE);
090
}
091
hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);
092
if (config.isTryHarder()) {
093
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
094
}
095
if (config.isPureBarcode()) {
096
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
097
}
098
return hints;
099
}
100
101
private static void addArgumentToInputs(String argument, Config config,
102
Inputs inputs) throws IOException {
103
File inputFile = new File(argument);
104
if (inputFile.exists()) {
105
inputs.addInput(inputFile.getCanonicalPath());
106
} else {
107
inputs.addInput(argument);
108
}
109
}
4)前端页面:
<script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script>
002
003 <script type="text/javascript">
004
005
$(document).ready(function(){
006
007
$("#qrcode_form").ajaxForm({
008
009
success:function(json){
010
011
if(json==null)
012
013
return;
014
015
json = eval("("+json+")");
016
017
if(json.msg){
018
019
alert(json.msg);
020
021
return;
022
023
}
024
025
if(json[0])
026
027
$("#result").val(json[0].text);
028
029
else
030
031
$("#result").val("解码失败");
032
033
}
034
035
});
036
037
$("#zxing").popover({
038
039
'title':'条形码处理类库 ZXing',
040
041
'content':'ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。',
042
043
'placement':'bottom'
044
045
});
046
047
});
048
049 </script>
050
051 <div id="mainContent" class="wrapper">
052
053 <div class="toolName">在线生成二维码(QR码)-采用<a id="zxing" href="http://www.oschina.net/p/zxing">ZXing</a>与<a href="http://www.d-project.com/">d-project</a><a data-toggle="modal" href="#advice" style="float:right;text-decoration:none;"><span class="badge badge-important"><i class="icon-envelope icon-white"></i> Feedback</span></a></div>
054
055 <div class="toolUsing clearfix">
056
057
<div class="toolsTab
clearfix">
058
059
<ul class="nav nav-tabs">
060
061
<li ><a href="/qr">转QR码</a></li>
062
063
<li class="active"><a href="/qr?type=2">二维码解码</a></li>
064
065
</ul>
066
067
<div class="clear"></div>
068
069
</div>
070
071
<form id="qrcode_form" method="post" action="/action/qrcode/decode">
072
073
<div class="topBar">
074
075
<div class="title">
076
077
<label class="radio" for="upload_url">图片URL:
078
079
<input checked="checked" name="upload_ctn" id="upload_url" style="margin-right:5px;" type="radio" onchange="if(this.checked){$('input[name='url']').removeAttr('disabled');$('input[name='qrcode']').attr('disabled','disabled')}"/>
080
081
</label>
082
083
</div>
084
085
<input name="url" id="url" style="width:100%;height:40px;margin:0 0 10px 0;" onfocus="if(this.value=='http://www.osctools.net/img/qr.gif'){this.value='';};this.select();" onblur="(this.value=='')?this.value='http://www.osctools.net/img/qr.gif':this.value;" value="http://www.osctools.net/img/qr.gif"/>
086
087
<div class="title">
088
089
<label
class="radio" for="upload_img">上传图片:
090
091
<input style="margin-right:5px;" name="upload_ctn" id="upload_img" type="radio" onchange="if(this.checked){$('input[name='qrcode']').removeAttr('disabled');$('input[name='url']').attr('disabled','disabled')}"/>
092
093
</label>
094
095
</div>
096
097
<input disabled="disabled" name="qrcode" type="file" class="input-file"/>
098
099
<input class="btn btn-primary" value="解码" type="submit"/>
100
101
</div>
102
103
<div class="bottomBar">
104
105
<div class="title">解码结果:</div>
106
107
<textarea id="result"></textarea>
108
109
</div>
110
111
</form>
112
113 </div>
114 </div>
注意:其中牵涉到的
RequestContext类见此处:
http://www.oschina.net/code/snippet_12_2
转载于:https://my.oschina.net/mkh/blog/150683
最后
以上就是发嗲月饼为你收集整理的Java实现生成和解码二维码具体操作步骤的全部内容,希望文章能够帮你解决Java实现生成和解码二维码具体操作步骤所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复