打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Java 生成 / 解码 QR码

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代码:

 

Java代码
 
  1. public void generate(RequestContext rc)   
  2.             throws UnsupportedEncodingException, IOException, ServletException {   
  3.                 //待转数据   
  4.         String data = rc.param("data""http://osctools.net/qr");   
  5.                 //输出图片类型   
  6.                 String output = rc.param("output""image/jpeg");   
  7.   
  8.         int type = rc.param("type"4);   
  9.         if (type < 0 || 10 < type) {   
  10.             return;   
  11.         }   
  12.   
  13.         int margin = rc.param("margin"10);   
  14.         if (margin < 0 || 32 < margin) {   
  15.             return;   
  16.         }   
  17.   
  18.         int cellSize = rc.param("size"4);   
  19.         if (cellSize < 1 || 4 < cellSize) {   
  20.             return;   
  21.         }   
  22.   
  23.         int errorCorrectLevel = 0;   
  24.   
  25.         try {   
  26.             errorCorrectLevel = parseErrorCorrectLevel(rc,   
  27.                     rc.param("error""H"));   
  28.         } catch (Exception e) {   
  29.             return;   
  30.         }   
  31.   
  32.         com.d_project.qrcode.QRCode qrcode = null;   
  33.         try {   
  34.             qrcode = getQRCode(data, type, errorCorrectLevel);   
  35.         } catch (Exception e) {   
  36.             return;   
  37.         }   
  38.   
  39.         if ("image/jpeg".equals(output)) {   
  40.   
  41.             BufferedImage image = qrcode.createImage(cellSize, margin);   
  42.   
  43.             rc.response().setContentType("image/jpeg");   
  44.   
  45.             OutputStream out = new BufferedOutputStream(rc.response()   
  46.                     .getOutputStream());   
  47.   
  48.             try {   
  49.                 ImageIO.write(image, "jpeg", out);   
  50.             } finally {   
  51.                 out.close();   
  52.             }   
  53.   
  54.         } else if ("image/png".equals(output)) {   
  55.   
  56.             BufferedImage image = qrcode.createImage(cellSize, margin);   
  57.   
  58.             rc.response().setContentType("image/png");   
  59.   
  60.             OutputStream out = new BufferedOutputStream(rc.response()   
  61.                     .getOutputStream());   
  62.   
  63.             try {   
  64.                 ImageIO.write(image, "png", out);   
  65.             } finally {   
  66.                 out.close();   
  67.             }   
  68.   
  69.         } else if ("image/gif".equals(output)) {   
  70.   
  71.             GIFImage image = createGIFImage(qrcode, cellSize, margin);   
  72.   
  73.             rc.response().setContentType("image/gif");   
  74.   
  75.             OutputStream out = new BufferedOutputStream(rc.response()   
  76.                     .getOutputStream());   
  77.   
  78.             try {   
  79.                 image.write(out);   
  80.             } finally {   
  81.                 out.close();   
  82.             }   
  83.   
  84.         } else {   
  85.             return;   
  86.         }   
  87.   
  88.     }   
  89.   
  90.     private static int parseErrorCorrectLevel(RequestContext rc, String ecl) {   
  91.         if ("L".equals(ecl)) {   
  92.             return ErrorCorrectLevel.L;   
  93.         } else if ("Q".equals(ecl)) {   
  94.             return ErrorCorrectLevel.Q;   
  95.         } else if ("M".equals(ecl)) {   
  96.             return ErrorCorrectLevel.M;   
  97.         } else if ("H".equals(ecl)) {   
  98.             return ErrorCorrectLevel.H;   
  99.         } 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)前端页面:

 

Html代码
 
  1. <script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script>  
  2.   
  3. <script type="text/javascript">  
  4.   
  5.     $(document).ready(function(){   
  6.   
  7.                 $("#submit").click(function(){   
  8.   
  9.             var url = "/action/qrcode/generate?" + $("#qrcode_form").serialize();   
  10.   
  11.             $(".QRCodeDiv img").attr("src",url+"&"+new Date().getTime());   
  12.   
  13.             $("#gen_url").attr("href",url);   
  14.   
  15.         });   
  16.   
  17.                 $("#zxing").popover({   
  18.   
  19.             'title':'条形码处理类库 ZXing',   
  20.   
  21.             'content':'ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。',   
  22.   
  23.             'placement':'bottom'   
  24.   
  25.         });   
  26.   
  27.     });   
  28.   
  29. </script>  
  30.   
  31. <div id="mainContent" class="wrapper">  
  32.   
  33. <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>  
  34.   
  35. <div class="toolUsing clearfix">  
  36.   
  37.     <div class="toolsTab  clearfix">  
  38.   
  39.         <ul class="nav nav-tabs">  
  40.   
  41.             <li class="active"><a href="/qr">转QR码</a></li>  
  42.   
  43.             <li ><a href="/qr?type=2">二维码解码</a></li>  
  44.   
  45.         </ul>  
  46.   
  47.         <div class="clear"></div>  
  48.   
  49.     </div>  
  50.   
  51.     <form id="qrcode_form" method="post" >  
  52.   
  53.             <div class="leftBar">  
  54.   
  55.             <div class="title">URL或其他文本:</div>  
  56.   
  57.             <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>  
  58.   
  59.         </div>  
  60.   
  61.         <div class="operateLR">  
  62.   
  63.             <div class="OptDetail span1">  
  64.   
  65.                 <label>输出格式:</label>  
  66.   
  67.                 <select name="output" class="span1">  
  68.   
  69.                     <option value="image/gif" selected>GIF</option>  
  70.   
  71.                     <option value="image/jpeg">JPEG</option>  
  72.   
  73.                     <option value="image/png">PNG</option>  
  74.   
  75.                 </select>  
  76.   
  77.                 <label>纠错级别:</label>  
  78.   
  79.                 <select name="error" class="span1">  
  80.   
  81.                     <option value="L" selected>L 7%</option>  
  82.   
  83.                     <option value="M">M 15%</option>  
  84.   
  85.                     <option value="Q">Q 25%</option>  
  86.   
  87.                     <option value="H">H 30%</option>  
  88.   
  89.                 </select>  
  90.   
  91.                 <label>类型:</label>  
  92.   
  93.                 <select name="type" class="span1">  
  94.   
  95.                     <option value="0">自动</option>  
  96.   
  97.                                         <option value="1">1</option>  
  98.   
  99.                                         <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代码:

 

Java代码
 
  1. @PostMethod  
  2.     @JSONOutputEnabled  
  3.     public void decode(RequestContext rc) throws IOException {   
  4.         //存在qrcode的网址   
  5.                 String url = rc.param("url""");   
  6.                 //待解码的qrcdoe图像   
  7.                 File img = rc.file("qrcode");   
  8.         if (StringUtils.isBlank(url) && img == null) {   
  9.             throw rc.error("qr_upload_or_url_null");   
  10.         }   
  11.   
  12.         List<Result> results = new ArrayList<Result>();   
  13.         Config config = new Config();   
  14.         Inputs inputs = new Inputs();   
  15.   
  16.         config.setHints(buildHints(config));   
  17.   
  18.         if (StringUtils.isNotBlank(url)) {   
  19.             addArgumentToInputs(url, config, inputs);   
  20.         }   
  21.         if (img != null) {   
  22.             inputs.addInput(img.getCanonicalPath());   
  23.         }   
  24.         while (true) {   
  25.             String input = inputs.getNextInput();   
  26.             if (input == null) {   
  27.                 break;   
  28.             }   
  29.             File inputFile = new File(input);   
  30.             if (inputFile.exists()) {   
  31.                 try {   
  32.                     Result result = decode(inputFile.toURI(), config,rc);   
  33.                     results.add(result);   
  34.                 } catch (IOException e) {   
  35.                 }   
  36.             } else {   
  37.                 try {   
  38.                     Result result = decode(new URI(input), config,rc);   
  39.                     results.add(result);   
  40.                 } catch (Exception e) {   
  41.                 }   
  42.             }   
  43.         }   
  44.         rc.print(new Gson().toJson(results));   
  45.     }   
  46.   
  47.     private Result decode(URI uri,Config config,RequestContext rc)   
  48.             throws IOException {   
  49.         Map<DecodeHintType, ?> hints = config.getHints();   
  50.         BufferedImage image;   
  51.         try {   
  52.             image = ImageIO.read(uri.toURL());   
  53.         } catch (IllegalArgumentException iae) {   
  54.             throw rc.error("qr_resource_not_found");   
  55.         }   
  56.         if (image == null) {   
  57.             throw rc.error("qr_could_not_load_image");   
  58.         }   
  59.         try {   
  60.             LuminanceSource source = new BufferedImageLuminanceSource(image);   
  61.             BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));   
  62.             Result result = new MultiFormatReader().decode(bitmap, hints);   
  63.             return result;   
  64.         } catch (NotFoundException nfe) {   
  65.             throw rc.error("qr_no_barcode_found");   
  66.         }   
  67.     }   
  68.   
  69.     private static Map<DecodeHintType, ?> buildHints(Config config) {   
  70.         Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(   
  71.                 DecodeHintType.class);   
  72.         Collection<BarcodeFormat> vector = new ArrayList<BarcodeFormat>(8);   
  73.         vector.add(BarcodeFormat.UPC_A);   
  74.         vector.add(BarcodeFormat.UPC_E);   
  75.         vector.add(BarcodeFormat.EAN_13);   
  76.         vector.add(BarcodeFormat.EAN_8);   
  77.         vector.add(BarcodeFormat.RSS_14);   
  78.         vector.add(BarcodeFormat.RSS_EXPANDED);   
  79.         if (!config.isProductsOnly()) {   
  80.             vector.add(BarcodeFormat.CODE_39);   
  81.             vector.add(BarcodeFormat.CODE_93);   
  82.             vector.add(BarcodeFormat.CODE_128);   
  83.             vector.add(BarcodeFormat.ITF);   
  84.             vector.add(BarcodeFormat.QR_CODE);   
  85.             vector.add(BarcodeFormat.DATA_MATRIX);   
  86.             vector.add(BarcodeFormat.AZTEC);   
  87.             vector.add(BarcodeFormat.PDF_417);   
  88.             vector.add(BarcodeFormat.CODABAR);   
  89.             vector.add(BarcodeFormat.MAXICODE);   
  90.         }   
  91.         hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);   
  92.         if (config.isTryHarder()) {   
  93.             hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);   
  94.         }   
  95.         if (config.isPureBarcode()) {   
  96.             hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);   
  97.         }   
  98.         return hints;   
  99.     }   
  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)前端页面:

 

Html代码
 
  1. <script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script>  
  2.   
  3. <script type="text/javascript">  
  4.   
  5.     $(document).ready(function(){   
  6.   
  7.                 $("#qrcode_form").ajaxForm({   
  8.   
  9.             success:function(json){   
  10.   
  11.                 if(json==null)   
  12.   
  13.                     return;   
  14.   
  15.                 json = eval("("+json+")");   
  16.   
  17.                 if(json.msg){   
  18.   
  19.                     alert(json.msg);   
  20.   
  21.                     return;   
  22.   
  23.                 }   
  24.   
  25.                 if(json[0])   
  26.   
  27.                     $("#result").val(json[0].text);   
  28.   
  29.                 else   
  30.   
  31.                     $("#result").val("解码失败");   
  32.   
  33.             }   
  34.   
  35.         });   
  36.   
  37.                 $("#zxing").popover({   
  38.   
  39.             'title':'条形码处理类库 ZXing',   
  40.   
  41.             'content':'ZXing是一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。',   
  42.   
  43.             'placement':'bottom'   
  44.   
  45.         });   
  46.   
  47.     });   
  48.   
  49. </script>  
  50.   
  51. <div id="mainContent" class="wrapper">  
  52.   
  53. <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>  
  54.   
  55. <div class="toolUsing clearfix">  
  56.   
  57.     <div class="toolsTab  clearfix">  
  58.   
  59.         <ul class="nav nav-tabs">  
  60.   
  61.             <li ><a href="/qr">转QR码</a></li>  
  62.   
  63.             <li class="active"><a href="/qr?type=2">二维码解码</a></li>  
  64.   
  65.         </ul>  
  66.   
  67.         <div class="clear"></div>  
  68.   
  69.     </div>  
  70.   
  71.     <form id="qrcode_form" method="post" action="/action/qrcode/decode">  
  72.   
  73.             <div class="topBar">  
  74.   
  75.             <div class="title">  
  76.   
  77.                 <label class="radio" for="upload_url">图片URL:   
  78.   
  79.                     <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')}"/>  
  80.   
  81.                 </label>  
  82.   
  83.             </div>  
  84.   
  85.             <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"/>  
  86.   
  87.             <div class="title">  
  88.   
  89.                 <label  class="radio" for="upload_img">上传图片:   
  90.   
  91.                     <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')}"/>  
  92.   
  93.                 </label>  
  94.   
  95.             </div>  
  96.   
  97.             <input disabled="disabled" name="qrcode" type="file" class="input-file"/>  
  98.   
  99.             <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类,请点击查看

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Thinkphp 5.0版本整合微信扫码支付接口,含模型验证异步通知等完整实例
网页自动生成二维码
二维码Java开发(笔记)
QR二维码生成器源码(中间可插入小图片)
Python 生成、解析二维码
java生成二维码的三个工具
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服