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代码:
复制代码
3)前端页面:
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
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 }
复制代码
058
059
060
061
062
063
208
209
224
225
226
227
228
229
064
065
066
067
076
077
078
079
090
091
092
093
118
119
120
121
190
191
192
193
204
205
206
207
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341<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代码:
复制代码
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
@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)前端页面:
复制代码
108
109
110
111
112
113
114
注意:其中牵涉到的
RequestContext类见此处:
http://www.oschina.net/code/snippet_12_2
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<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>
转载于:https://my.oschina.net/mkh/blog/150683
最后
以上就是发嗲月饼最近收集整理的关于Java实现生成和解码二维码具体操作步骤的全部内容,更多相关Java实现生成和解码二维码具体操作步骤内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复