Java 產生 / 解碼 QR碼

來源:互聯網
上載者:User

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)throws UnsupportedEncodingException, IOException, ServletException {                //待轉資料String data = rc.param("data", "http://osctools.net/qr");                //輸出圖片類型                String output = rc.param("output", "image/jpeg");int type = rc.param("type", 4);if (type < 0 || 10 < type) {return;}int margin = rc.param("margin", 10);if (margin < 0 || 32 < margin) {return;}int cellSize = rc.param("size", 4);if (cellSize < 1 || 4 < cellSize) {return;}int errorCorrectLevel = 0;try {errorCorrectLevel = parseErrorCorrectLevel(rc,rc.param("error", "H"));} catch (Exception e) {return;}com.d_project.qrcode.QRCode qrcode = null;try {qrcode = getQRCode(data, type, errorCorrectLevel);} catch (Exception e) {return;}if ("image/jpeg".equals(output)) {BufferedImage image = qrcode.createImage(cellSize, margin);rc.response().setContentType("image/jpeg");OutputStream out = new BufferedOutputStream(rc.response().getOutputStream());try {ImageIO.write(image, "jpeg", out);} finally {out.close();}} else if ("image/png".equals(output)) {BufferedImage image = qrcode.createImage(cellSize, margin);rc.response().setContentType("image/png");OutputStream out = new BufferedOutputStream(rc.response().getOutputStream());try {ImageIO.write(image, "png", out);} finally {out.close();}} else if ("image/gif".equals(output)) {GIFImage image = createGIFImage(qrcode, cellSize, margin);rc.response().setContentType("image/gif");OutputStream out = new BufferedOutputStream(rc.response().getOutputStream());try {image.write(out);} finally {out.close();}} else {return;}}private static int parseErrorCorrectLevel(RequestContext rc, String ecl) {if ("L".equals(ecl)) {return ErrorCorrectLevel.L;} else if ("Q".equals(ecl)) {return ErrorCorrectLevel.Q;} else if ("M".equals(ecl)) {return ErrorCorrectLevel.M;} else if ("H".equals(ecl)) {return ErrorCorrectLevel.H;} else {throw rc.error("qr_error_correct_error");}}private static QRCode getQRCode(String text, int typeNumber,int errorCorrectLevel) throws IllegalArgumentException {if (typeNumber == 0) {return QRCode.getMinimumQRCode(text, errorCorrectLevel);} else {QRCode qr = new QRCode();qr.setTypeNumber(typeNumber);qr.setErrorCorrectLevel(errorCorrectLevel);qr.addData(text);qr.make();return qr;}}private static GIFImage createGIFImage(QRCode qrcode, int cellSize,int margin) throws IOException {int imageSize = qrcode.getModuleCount() * cellSize + margin * 2;GIFImage image = new GIFImage(imageSize, imageSize);for (int y = 0; y < imageSize; y++) {for (int x = 0; x < imageSize; x++) {if (margin <= x && x < imageSize - margin && margin <= y&& y < imageSize - margin) {int col = (x - margin) / cellSize;int row = (y - margin) / cellSize;if (qrcode.isDark(row, col)) {image.setPixel(x, y, 0);} else {image.setPixel(x, y, 1);}} else {image.setPixel(x, y, 1);}}}return image;}

  

    3)前端頁面:

<script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script><script type="text/javascript">$(document).ready(function(){$("#submit").click(function(){var url = "/action/qrcode/generate?" + $("#qrcode_form").serialize();$(".QRCodeDiv img").attr("src",url+"&"+new Date().getTime());$("#gen_url").attr("href",url);});    $("#zxing").popover({    'title':'條碼處理類庫 ZXing',    'content':'ZXing是一個開源Java類庫用於解析多種格式的1D/2D條碼。目標是能夠對QR編碼、Data Matrix、UPC的1D條碼進行解碼。 其提供了多種平台下的用戶端包括:J2ME、J2SE和Android。','placement':'bottom'    });});</script><div id="mainContent" class="wrapper"><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><div class="toolUsing clearfix"><div class="toolsTab  clearfix">    <ul class="nav nav-tabs">            <li class="active"><a href="/qr">轉QR碼</a></li>            <li ><a href="/qr?type=2">二維碼解碼</a></li>    </ul>    <div class="clear"></div></div><form id="qrcode_form" method="post" >    <div class="leftBar"><div class="title">URL或其他文本:</div><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>    </div>    <div class="operateLR">            <div class="OptDetail span1">            <label>輸出格式:</label>                <select name="output" class="span1">                    <option value="image/gif" selected>GIF</option>                    <option value="image/jpeg">JPEG</option>                    <option value="image/png">PNG</option>                </select>                <label>錯誤修正層級:</label>                <select name="error" class="span1">                    <option value="L" selected>L 7%</option>                    <option value="M">M 15%</option>                    <option value="Q">Q 25%</option>                    <option value="H">H 30%</option>                </select>                <label>類型:</label>        <select name="type" class="span1">                    <option value="0">自動</option>                                        <option value="1">1</option>                                        <option value="2">2</option>                                        <option value="3">3</option>                                        <option value="4">4</option>                                        <option value="5">5</option>                                        <option value="6">6</option>                                        <option value="7">7</option>                                        <option value="8">8</option>                                        <option value="9">9</option>                                        <option value="10">10</option>                                    </select>                <label>邊緣留白:</label>    <select name="margin" class="span1">                                        <option value="0">0</option>                                        <option value="1">1</option>                                        <option value="2">2</option>                                        <option value="3">3</option>                                        <option value="4">4</option>                                        <option value="5">5</option>                                        <option value="6">6</option>                                        <option value="7">7</option>                                        <option value="8">8</option>                                        <option value="9">9</option>                                        <option value="10">10</option>                                        <option value="11">11</option>                                        <option value="12">12</option>                                        <option value="13">13</option>                                        <option value="14">14</option>                                        <option value="15">15</option>                                        <option value="16">16</option>                                        <option value="17">17</option>                                        <option value="18">18</option>                                        <option value="19">19</option>                                        <option value="20">20</option>                                        <option value="21">21</option>                                        <option value="22">22</option>                                        <option value="23">23</option>                                        <option value="24">24</option>                                        <option value="25">25</option>                                        <option value="26">26</option>                                        <option value="27">27</option>                                        <option value="28">28</option>                                        <option value="29">29</option>                                        <option value="30">30</option>                                        <option value="31">31</option>                                        <option value="32">32</option>                                    </select>                <label>原胞大小:</label>    <select name="size" class="span1">                                        <option value="1"  >1</option>                                        <option value="2"  >2</option>                                        <option value="3"  >3</option>                                        <option value="4" selected >4</option>                        </select><button class="btn btn-small btn-primary" id="submit" onclick="return false;">產生QR碼</button>            </div>    </div>    <div class="rightBar"><div class="title">QR碼:</div>            <div class="QRCodeDiv"><div class="QRWrapper"><a id="gen_url" href="/action/qrcode/generate?size=4" target="_blank"><img src="/action/qrcode/generate?size=4"/></a></div></div>    </div>    </form></div></div>

  

4、使用ZXing解碼QRcode

    1)下載Zxing-2.0.zip

    2)引入zxing-barcode_core.jar與zxing_barcode_j2se.jar到工程

    3)QRcodeAction代碼:

@PostMethod@JSONOutputEnabledpublic void decode(RequestContext rc) throws IOException {//存在qrcode的網址                String url = rc.param("url", "");                //待解碼的qrcdoe映像                File img = rc.file("qrcode");if (StringUtils.isBlank(url) && img == null) {throw rc.error("qr_upload_or_url_null");}List<Result> results = new ArrayList<Result>();Config config = new Config();Inputs inputs = new Inputs();config.setHints(buildHints(config));if (StringUtils.isNotBlank(url)) {addArgumentToInputs(url, config, inputs);}if (img != null) {inputs.addInput(img.getCanonicalPath());}while (true) {String input = inputs.getNextInput();if (input == null) {break;}File inputFile = new File(input);if (inputFile.exists()) {try {Result result = decode(inputFile.toURI(), config,rc);results.add(result);} catch (IOException e) {}} else {try {Result result = decode(new URI(input), config,rc);results.add(result);} catch (Exception e) {}}}rc.print(new Gson().toJson(results));}private Result decode(URI uri,Config config,RequestContext rc)throws IOException {Map<DecodeHintType, ?> hints = config.getHints();BufferedImage image;try {image = ImageIO.read(uri.toURL());} catch (IllegalArgumentException iae) {throw rc.error("qr_resource_not_found");}if (image == null) {throw rc.error("qr_could_not_load_image");}try {LuminanceSource source = new BufferedImageLuminanceSource(image);BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));Result result = new MultiFormatReader().decode(bitmap, hints);return result;} catch (NotFoundException nfe) {throw rc.error("qr_no_barcode_found");}}private static Map<DecodeHintType, ?> buildHints(Config config) {Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);Collection<BarcodeFormat> vector = new ArrayList<BarcodeFormat>(8);vector.add(BarcodeFormat.UPC_A);vector.add(BarcodeFormat.UPC_E);vector.add(BarcodeFormat.EAN_13);vector.add(BarcodeFormat.EAN_8);vector.add(BarcodeFormat.RSS_14);vector.add(BarcodeFormat.RSS_EXPANDED);if (!config.isProductsOnly()) {vector.add(BarcodeFormat.CODE_39);vector.add(BarcodeFormat.CODE_93);vector.add(BarcodeFormat.CODE_128);vector.add(BarcodeFormat.ITF);vector.add(BarcodeFormat.QR_CODE);vector.add(BarcodeFormat.DATA_MATRIX);vector.add(BarcodeFormat.AZTEC);vector.add(BarcodeFormat.PDF_417);vector.add(BarcodeFormat.CODABAR);vector.add(BarcodeFormat.MAXICODE);}hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);if (config.isTryHarder()) {hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);}if (config.isPureBarcode()) {hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);}return hints;}private static void addArgumentToInputs(String argument, Config config,Inputs inputs) throws IOException {File inputFile = new File(argument);if (inputFile.exists()) {inputs.addInput(inputFile.getCanonicalPath());} else {inputs.addInput(argument);}}

 

  4)前端頁面:

<script type="text/javascript" src="/js/jquery/jquery.form-2.82.js"></script><script type="text/javascript">$(document).ready(function(){$("#qrcode_form").ajaxForm({success:function(json){if(json==null)return;json = eval("("+json+")");if(json.msg){alert(json.msg);return;}if(json[0])$("#result").val(json[0].text);else$("#result").val("解碼失敗");}});    $("#zxing").popover({    'title':'條碼處理類庫 ZXing',    'content':'ZXing是一個開源Java類庫用於解析多種格式的1D/2D條碼。目標是能夠對QR編碼、Data Matrix、UPC的1D條碼進行解碼。 其提供了多種平台下的用戶端包括:J2ME、J2SE和Android。','placement':'bottom'    });});</script><div id="mainContent" class="wrapper"><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><div class="toolUsing clearfix"><div class="toolsTab  clearfix">    <ul class="nav nav-tabs">            <li ><a href="/qr">轉QR碼</a></li>            <li class="active"><a href="/qr?type=2">二維碼解碼</a></li>    </ul>    <div class="clear"></div></div><form id="qrcode_form" method="post" action="/action/qrcode/decode">    <div class="topBar">            <div class="title"><label class="radio" for="upload_url">圖片URL:<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')}"/></label></div><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"/>            <div class="title"><label  class="radio" for="upload_img">上傳圖片:<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')}"/></label></div><input disabled="disabled" name="qrcode" type="file" class="input-file"/>    <input class="btn btn-primary" value="解碼" type="submit"/>    </div><div class="bottomBar"><div class="title">解碼結果:</div><textarea id="result"></textarea>        </div>    </form></div></div>

注意:其中牽涉到的RequestContext類見此處:http://www.oschina.net/code/snippet_12_2

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.