扫码登录,将请求路径制作成二维码

今天,写了一个二维码制作的工具类,在这里和大家分享一下。

需要在pom文件中添加jar包


   com.google.zxing
   core
   3.2.1

java代码

package com.maque.boothero.common;

import com.alibaba.druid.util.StringUtils;
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 java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Hashtable;

/**
 * @program: boot-hero
 * @description: 生成二维码工具类
 * @author: maque
 * @create: 2018-07-19 18:01
 */
public class QRCodeImageUtil {

    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    // 说明文本高度
    private static final int HEIGHT_TEXT = 30;
    // LOGO宽度
    private static final int WIDTH_LOGO = 110;
    // LOGO高度
    private static final int HEIGHT_LOGO = 110;

    private static final String Encoding = "utf-8";
    private static final String FORMAT_NAME = "JPG";

    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    public static void main(String[] args) {
        String content = "http://www.baidu.com";//可以将此处的地址换成你的登录地址
        String text = "百度一下就知道,百度一下就知道,百度一下就知道,百度一下就知道,百度一下就知道,";
        try {
            FileInputStream is = new FileInputStream(new File("E:\\temp\\toPDF\\555.jpg"));
            ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int ch;
            while ((ch = is.read(buffer)) != -1) {
                bytestream.write(buffer,0,ch);
            }
            byte[] data = bytestream.toByteArray();
            bytestream.close();
//          byte[] imageBody = createQRCode("http://www.baidu.com");
//          byte[] imageBody = createQRCodeWithText(content,text);
//          byte[] imageBody = createQRCodeWithLogo(content,data);
            byte[] imageBody = createQRCodeWithLogoAndText(content,text,data);
            String filename = DateUtil.getCurrentDateTimeToStr()+ ".jpg";
            FileOutputStream os = new FileOutputStream(new File("E:\\temp\\toPDF\\"+filename));
            os.write(imageBody);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     *
     *
     * @param content 二维码内容
     * @return 二维码图片字节数组
     */
    public static byte[] createQRCode(String content){
        if (StringUtils.isNumber(content)) {
            return null;
        }
        Hashtable hints = new Hashtable();
        // ErrorCorrectionLevel.H 容错率:容错率越高,纠错等级越高,算法越复杂,
        // 解析软件识别出其内容的机率越大(你的logo就可以设置的更大)。
        // 但是二维码所存储的内容也越少,可丢失的数据也就越多;
        /*L = ~7% correction
        L(0x01),
        M = ~15% correction
        M(0x00),
        Q = ~25% correction
        Q(0x03),
        H = ~30% correction
        H(0x02);*/
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 使用小写的编码,大写会出现]Q2\000026开头内容
        hints.put(EncodeHintType.CHARACTER_SET, Encoding);
        //边缘空白
        hints.put(EncodeHintType.MARGIN, 1);

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content,    BarcodeFormat.QR_CODE,QRCODE_SIZE,QRCODE_SIZE,hints);
            BufferedImage image = new BufferedImage(bitMatrix.getWidth(), bitMatrix.getHeight(), BufferedImage.TYPE_INT_RGB);
            for (int w = 0; w < image.getWidth(); w++ ) {
                for (int h = 0; h < image.getHeight(); h++ ) {
                    //bitMatrix.get(w,h) 返回的是Boolean类型,true (w,h)此点为黑色,false(w,h)此点像素为白色
                    image.setRGB(w,h,bitMatrix.get(w,h) ? BLACK : WHITE);
                }
            }
            //将图片转换成byte数组
            ImageIO.write(image,FORMAT_NAME,output);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return output.toByteArray();
    }

    /**
     * 生成二维码(包含说明文本,不包含LOGO)
     *
     * @param content 二维码内容
     * @param text 说明文本
     * @return 二维码图片字节数组
     */
    public static byte[] createQRCodeWithText(String content,String text){

        try {
            byte [] imageBody = createQRCode(content);
            if (!StringUtils.isNumber(text) ) {

                int num = QRCODE_SIZE / 26;
                int textNum = text.length();
                if (textNum > num ) {
                    String firstLine = text.substring(0,num);
                    byte[] firstLineBody = insertText(imageBody,firstLine);
                    String lastLine = text.substring(num,text.length());
                    byte[] lastLineBody = insertText(firstLineBody,lastLine);
                    return lastLineBody;
                } else {
                    byte[] lastLineBody = insertText(imageBody,text);
                    return lastLineBody;
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 向二维码中插入说明文
     *
     * @param imageBody 二维码图片
     * @param text 说明文
     * @return 二维码图片字节数组
     */
    public static byte[] insertText(byte[] imageBody,String text){
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(imageBody);
            BufferedImage image = ImageIO.read(bais);

            if (!StringUtils.isNumber(text) ) {
                int num = QRCODE_SIZE / 26;
                int textNum = text.length();
                if (textNum > num) {
                    String firstLine = text.substring(0,num);
                    byte[] firstLineBody = insertText(imageBody,firstLine);
                    String lastLine = text. substring(num,text.length());
                    byte[] lastLineBody = insertText(firstLineBody,lastLine);
                    return lastLineBody;
                }
            }
            //创建一个新的图片底板。宽度不变,高度加上一个文本的高度。
            BufferedImage outImage = new BufferedImage(image.getWidth(), image.getHeight() + HEIGHT_TEXT, BufferedImage.TYPE_INT_RGB);
            Graphics2D outg = outImage.createGraphics();

            // 画二维码到新的面板
            outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);

            //将文本背景设置成白色。
            for (int x = 0; x < image.getWidth(); x++) {
                for (int y = image.getHeight(); y < (outImage.getHeight()); y++) {
                    outImage.setRGB(x, y, WHITE);
                }
            }

            // 画文字到新的面板
            outg.setColor(Color.BLACK);
            outg.setFont(new Font("宋体", Font.BOLD, 25)); // 字体、字型、字号 25号字大约是26像素(包含字之间的空隙)

            int strWidth = outg.getFontMetrics().stringWidth(text);
            if (strWidth > QRCODE_SIZE) {
                // 画文字  向左对齐
                outg.drawString(text, 0, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12);
            } else {
                // 画文字 居中
                outg.drawString(text, QRCODE_SIZE / 2 - strWidth / 2, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12);
            }

            outg.dispose();//释放资源
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(outImage,FORMAT_NAME,os);
            return os.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成二维码(内嵌LOGO,不包含说明文本)
     *
     * @param content 二维码内容
     * @param logo 图片
     * @return 二维码图片字节数组
     */
    public static byte[] createQRCodeWithLogo(String content, byte[] logo){
        if (!StringUtils.isEmpty(content)) {
            byte [] imageBody = createQRCode(content);
            ByteArrayInputStream bais = null;
            try {
                bais = new ByteArrayInputStream(imageBody);
                BufferedImage source = ImageIO.read(bais);
                if (null == logo || logo.length== 0) {
                    System.out.println("该图片不存在!");
                    return null;
                }
                bais = new ByteArrayInputStream(logo);
                Image src = ImageIO.read(bais);
                int width = src.getWidth(null);
                int height = src.getHeight(null);
                if (true) { //压缩LOGO
                    if (width > WIDTH_LOGO) {
                        width = WIDTH_LOGO;
                    }
                    if (height > HEIGHT_LOGO) {
                        height = HEIGHT_LOGO;
                    }
                    Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                    BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                    Graphics g = tag.getGraphics();
                    g.drawImage(image, 0, 0, null);
                    g.dispose();
                    src = image;
                }
                // 插入LOGO
                Graphics2D graph = source.createGraphics();
                int x = (QRCODE_SIZE - width) / 2;
                int y = (QRCODE_SIZE - height) / 2;
                graph.drawImage(src, x, y, width, height, null);
                Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
                graph.setStroke(new BasicStroke(3f));
                graph.draw(shape);
                graph.dispose();
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                ImageIO.write(source,FORMAT_NAME,os);
                return os.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;
    }

    /**
     * 生成二维码(内嵌LOGO,含说明文本)
     *
     * @param conten 二维码内容
     * @param text 说明文
     * @param logo 图片
     * @return 二维码图片字节数组
     */
    public static byte[] createQRCodeWithLogoAndText(String content, String text,byte[] logo){
        return insertText(createQRCodeWithLogo(content,logo),text);
    }

}

运行结果:

扫码登录,将请求路径制作成二维码_第1张图片

欢迎大家使用

 

你可能感兴趣的:(扫码登录,将请求路径制作成二维码)