java二维码生成 zxing

二维码分类
线性堆叠二维码
邮政码
矩阵式二维码(常用) 通过矩形空间黑白像素不同分布进行编码。点出现是1,不出现0.比如QR Code

二维码的优点:高密度编码,信息容量大;编码范围广;容错能力强;译码可靠性高;可引入加密措施;成本低,易制作,持久耐用。
缺点:手机病毒、钓鱼网站传播渠道

注意:添加http://头才会识别为链接而不是文本

使用google的zxing
官方github
maven配置

 
            com.google.zxing
            javase
            3.3.0
        
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;



import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author icecrea on 18-1-5
 */
public class QRCodeUtil {
    private static final int width = 300;// 默认二维码宽度
    private static final int height = 300;// 默认二维码高度
    private static final String format = "png";// 默认二维码文件格式
    private static final Map hints = new HashMap();// 二维码参数

    static {
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");// 字符编码
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);// 容错等级 L、M、Q、H 其中 L 为最低, H 为最高
        hints.put(EncodeHintType.MARGIN, 2);// 二维码与图片边距
    }
    /**
     * 返回一个 BufferedImage 对象
     * @param content 二维码内容
     * @param width   宽
     * @param height  高
     */
    public static BufferedImage toBufferedImage(String content, int width, int height) throws WriterException, IOException {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        return MatrixToImageWriter.toBufferedImage(bitMatrix);
    }
    /**
     * 将二维码图片输出到一个流中
     * @param content 二维码内容
     * @param stream  输出流
     * @param width   宽
     * @param height  高
     */
    public static void writeToStream(String content, OutputStream stream, int width, int height) throws WriterException, IOException {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        MatrixToImageWriter.writeToStream(bitMatrix, format, stream);
    }
    /**
     * 生成二维码图片文件
     * @param content 二维码内容
     * @param path    文件保存路径
     * @param width   宽
     * @param height  高
     */
    public static void createQRCode(String content, String path, int width, int height) throws WriterException, IOException {
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        //toPath() 方法由 jdk1.7 及以上提供
        MatrixToImageWriter.writeToPath(bitMatrix, format, new File(path).toPath());
    }

    public static void main(String[] args) throws Exception {
        OutputStream outputStream=new FileOutputStream(new File("/home/icecrea/hello.png"));
        QRCodeUtil.writeToStream("www.baidu.com",outputStream,width,height);
        QRCodeUtil.createQRCode("www.qunar.com","/home/icecrea/qunar.png",width,height);
    }
}

在spring mvc中,可以通过流的形式在显示图片,抽象出如下工具类

public class QRCodeUtil {
    private static Logger logger = LoggerFactory.getLogger(QRCodeUtil.class);
    // 默认二维码宽度
    private static final int width = 300;
    // 默认二维码高度
    private static final int height = 300;
    // 默认二维码文件格式
    private static final String format = "png";
    // 二维码参数
    private static final Map hints = new HashMap();
 
    static {
        // 字符编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 容错等级 L、M、Q、H 其中 L 为最低, H 为最高
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 二维码与图片边距
        hints.put(EncodeHintType.MARGIN, 2);
    }
 
    public static void generateQRCode(String url, HttpServletResponse response) throws Exception {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "连接地址为空");
        generateQRCode(url,response,height,width);
    }
 
    public static void generateQRCode(String url, HttpServletResponse response, int height, int width) throws Exception {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "连接地址为空");
        OutputStream stream = null;
        try {
            stream = response.getOutputStream();
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, height, width, hints);
            MatrixToImageWriter.writeToStream(bitMatrix, format, stream);
        } finally {
            if (stream != null) {
                stream.close();
            }
        }
    }
}

@RequestMapping("qrcode")
public void qrcode(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse){
    try {
        QRCodeUtil.generateQRCode("http://www.qunar.com",httpServletResponse);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

生成Logo版本

package com.sdu.util;

import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;

/**
 * @author ligen
 * @create 2018-01-09 下午9:02
 */
public class QRCodeUtil {
    /**
     * 默认二维码宽度
     */
    private static final int width = 300;
    /**
     * 默认二维码高度
     */
    private static final int height = 300;
    /**
     * 默认二维码文件格式
     */
    private static final String format = "png";
    /**
     * 二维码参数
     */
    private static final Map hints = new HashMap();

    static {
        // 字符编码
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        // 容错等级 L、M、Q、H 其中 L 为最低, H 为最高
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 二维码与图片边距
        hints.put(EncodeHintType.MARGIN, 1);
    }

    public static void generateQRCode(String url, HttpServletResponse response) throws Exception {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "连接地址为空");
        generateQRCode(url,response,height,width);
    }

    public static void generateQRCode(String url, HttpServletResponse response, int height, int width) {
        Preconditions.checkArgument(!Strings.isNullOrEmpty(url), "连接地址为空");

        try (OutputStream stream= response.getOutputStream()){
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, height, width, hints);
//            MatrixToImageWriter.writeToStream(bitMatrix, format, stream);
            BufferedImage bufferedImage=toBufferedImage(bitMatrix);
            bufferedImage=setMatrixLogo(bufferedImage,"http://i.ce.cn/ce/aero/201601/04/W020160104629730930933.jpg");
            ImageIO.write(bufferedImage,format,stream);
        } catch (Exception e){
//            log.error("生成二维码失败",e);
        }
    }

    public static BufferedImage setMatrixLogo(BufferedImage matrixImage,String logUri) throws IOException{
        /**
         * 读取二维码图片,并构建绘图对象
         */
        Graphics2D g2 = matrixImage.createGraphics();
        int matrixWidth = matrixImage.getWidth();
        int matrixHeigh = matrixImage.getHeight();

        /**
         * 读取Logo图片
         */
        BufferedImage logo = ImageIO.read(new URL(logUri));

        //开始绘制图片
        g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);
        //绘制边框
        BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
        // 设置笔画对象
        g2.setStroke(stroke);
        //指定弧度的圆角矩形
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);
        g2.setColor(Color.white);
        // 绘制圆弧矩形
        g2.draw(round);

        //设置logo 有一道灰色边框
        BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
        // 设置笔画对象
        g2.setStroke(stroke2);
        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);
        g2.setColor(new Color(128,128,128));
        g2.draw(round2);// 绘制圆弧矩形


        g2.dispose();
        matrixImage.flush() ;
        return matrixImage ;
    }

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y,  (matrix.get(x, y) ? BLACK : WHITE));
//              image.setRGB(x, y,  (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));
            }
        }
        return image;
    }

}

参考文章:
https://www.jianshu.com/p/05e9ee773898
https://www.jianshu.com/p/7ae3b7002530

你可能感兴趣的:(java二维码生成 zxing)