工具(十):Java二维码操作工具类

来源:互联网 发布:centos 删除目录 编辑:程序博客网 时间:2024/06/05 04:58

1. 二维码基础

1.1概念

二维码:某种特定几何图形按一定规律在平面上分布的条,空相间的图形来记录数据符号的信息。

1.2分类

线性堆叠式二维码;
矩阵式二维码;
邮政码。

2.国家标准GB

 

3.QR Code类二维码

3.1ZXing工具生成/解析

ZXing: https://github.com/zxing

需要引入zxing-3.2.1.jar

package com.wdy.utils;

import com.google.common.collect.Maps;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.datamatrix.encoder.ErrorCorrection;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.http.HttpResponse;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.io.Writer;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by wangdy on 2017/7/20.
 */
public class ZXingUtil {

    
public static void main(String[] args) {
//        createZXingQRCodeToFile(300, 300, "png", "I am wangdy,哈哈", "qrcode.png");
        
Map<StringObjectstringObjectMap readZXingQRCodeToFile("qrcode.png");
        
System.out.println("" stringObjectMap.get("result"));

    
}

    
/**
     * 
使用ZXing工具生成qrcode二维码---到文件
     
*
     * 
@param width    宽度
     
@param height   高度
     
@param format   扩展名 eg png
     * 
@param content  文字内容
     
@param filePath 输出文件路径
     
@date:2017/7/20 23:29
     */
    
public static void createZXingQRCodeToFile(int widthint heightString formatString contentString filePath) {
        
HashMap hints new HashMap();
        
//设置文字编码
        
hints.put(EncodeHintType.CHARACTER_SET"utf-8");
        
//设置容错等级,常用M
        
hints.put(EncodeHintType.ERROR_CORRECTIONErrorCorrectionLevel.M);
        
//设置二维码四周空白,默认5
        
hints.put(EncodeHintType.MARGIN2);
        
try {
            
BitMatrix bitMatrix new MultiFormatWriter().encode(contentBarcodeFormat.QR_CODEwidthheighthints);
            
Path path new File(filePath).toPath();
            
MatrixToImageWriter.writeToPath(bitMatrixformatpath);
        
catch (Exception e) {
            e
.printStackTrace();
        
}
    }

    
/**
     * 
使用ZXing工具解析二维码
     
*
     * 
@param filePath 文件路径
     
@date:2017/7/20 23:29
     * 
@return Map:<"result",value>,<"textResult",value>,<"barcodeFormat",value>
     */
    
public static Map<StringObjectreadZXingQRCodeToFile(String filePath) {
        
Map<StringObjectresultMap Maps.newHashMap();
        
MultiFormatReader multiFormatReader new MultiFormatReader();
        
File file new File(filePath);
        
try {
            
BufferedImage bufferedImage ImageIO.read(file);
            
BinaryBitmap binaryBitmap new BinaryBitmap(new HybridBinarizer(new BufferedImageLuminanceSource(bufferedImage)));
            
HashMap hints new HashMap();
            
//设置文字编码
            
hints.put(EncodeHintType.CHARACTER_SET"utf-8");
            
Result result multiFormatReader.decode(binaryBitmaphints);

            
System.out.println("解析结果: " result.toString());
            
System.out.println("解析文本内容:" result.getText());
            
System.out.println("二维码类型:" result.getBarcodeFormat());
            
/*解析结果: I am wangdy,哈哈
            
解析文本内容:I am wangdy,哈哈
            
二维码类型:QR_CODE*/

            
resultMap.put("result"result.toString());
            
resultMap.put("textResult"result.getText());
            
resultMap.put("barcodeFormat"result.getBarcodeFormat());
        
catch (Exception e) {
            e
.printStackTrace();
        
}
        
return resultMap;
    
}

3.2QECode工具生成/解析

生成二维码jar:http://www.swetake.com/qrcode/

解析二维码jar:https://zh.osdn.net/projects/qrcode/

1)将下载下来的jar重命名后,安装到本地maven仓库中:

2)引入到工程

3)代码:

package com.wdy.utils;    import com.swetake.util.Qrcode;  import jp.sourceforge.qrcode.QRCodeDecoder;    import javax.imageio.ImageIO;  import java.awt.*;  import java.awt.image.BufferedImage;  import java.io.File;  import java.io.IOException;  import java.io.UnsupportedEncodingException;    /** * 使用QRCode工具生成解析二维码 * Created by wangdy on 2017/7/21. */  public class QRCodeUtil {    /**     * 使用QRCode工具生成 二维码     *     * @param qrcodeVersion 版本号 一般用7     * @param content       填充文字     * @param format        扩展名 如png     * @param filePath      生成的文件路径     * @return     * @date:2017/7/21 10:10     */    public static void createQRCByQRCode(int qrcodeVersion, String content, String format, String filePath) {        Qrcode qrcode = new Qrcode();        qrcode.setQrcodeErrorCorrect('M');        //N代表数字,A代表字母,B代表其他字符,通常B        qrcode.setQrcodeEncodeMode('B');        qrcode.setQrcodeVersion(qrcodeVersion);//版本号        int width = 67 + 12 * (qrcodeVersion - 1);//固定公式        int height = 67 + 12 * (qrcodeVersion - 1);        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);          Graphics2D graphics2D = bufferedImage.createGraphics();        graphics2D.setBackground(Color.WHITE);        graphics2D.setColor(Color.BLACK);        graphics2D.clearRect(0, 0, width, height);          int pixoff = 2;//偏移量,绘图使用          byte[] bytes = new byte[0];        try {            bytes = content.getBytes("utf-8");//中文支持        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        if (bytes.length > 0 && bytes.length < 120) {            boolean[][] s = qrcode.calQrcode(bytes);            for (int i = 0; i < s.length; i++) {                for (int j = 0; j < s.length; j++) {                    if (s[j][i]) {                        graphics2D.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);                    }                }            }            graphics2D.dispose();            bufferedImage.flush();            try {                File file = new File(filePath);                boolean write = ImageIO.write(bufferedImage, format, file);                if (write) {                    System.out.println("生成二维码成功:位置" + file.getAbsolutePath());                    //生成二维码成功:位置E:\mycode\jdbcTempDemo\qrcodecreate.png                }            } catch (IOException e) {                e.printStackTrace();            }        }    }        /**     * 使用QRCode工具生成 二维码     *     * @param filePath 生成的文件路径     * @return     * @date:2017/7/21 10:10     */    public static String readQRCByQRCode(String filePath) {        File file = new File(filePath);        String result = "";        try {            BufferedImage bufferedImage = ImageIO.read(file);            QRCodeDecoder qrCodeDecoder = new QRCodeDecoder();  //            byte[] decode = qrCodeDecoder.decode(new MyQRCodeImage(bufferedImage));            result = new String(qrCodeDecoder.decode(new MyQRCodeImage(bufferedImage)), "utf-8");            System.out.println("解析结果为:" + result);          } catch (Exception e) {            e.printStackTrace();        }        return result;    }      public static void main(String[] args) {  //        createQRCByQRCode(7, "I am your father,哦也!", "png", "qrcodecreate.png");        String result = readQRCByQRCode("123.png");        System.out.println("" + result);    }}

3.3jquery-qrcode生成二维码

https://github.com/jeromeetienne/jquery-qrcode

<%@ page contentType="text/html;charset=UTF-8" language="java" %>  <html><head>    <title>Title</title>    <%--注意顺序--%>    <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery.min.js"></script>    <script type="text/javascript" src="<%=request.getContextPath() %>/js/jquery.qrcode.min.js"></script></head><body>  生成的二维码如下:
<%--注意顺序--%>
<div id="qrcode"></div><script type="text/javascript">    jQuery('#qrcode').qrcode({width: 120, height: 120, text: utf16to8("this is content中12文")});
//支持中文方法    function utf16to8(str) {        var out, i, len, c;        out = "";        len = str.length;        for (i = 0; i < len; i++) {            c = str.charCodeAt(i);            if ((c >= 0x0001) && (c <= 0x007F)) {                out += str.charAt(i);            } else if (c > 0x07FF) {                out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));                out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));                out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));            } else {                out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));                out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));            }        }        return out;    }</script></body></html>

特别注意问题:jquery-qrcode生成的二维码用微信/支付宝可以正常扫描,用ZxingUtil工具也可以解析,但用QRCode.jar无法正常解析,错误如下/还有一种可能是解析出的是乱码。
jp.sourceforge.qrcode.exception.DecodingFailedException: Give up decoding
        at jp.sourceforge.qrcode.QRCodeDecoder.decode(QRCodeDecoder.java:88)
        at com.wdy.utils.QRCodeUtil.readQRCByQRCode(QRCodeUtil.java:90)
        at com.wdy.utils.QRCodeUtil.main(QRCodeUtil.java:101)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)