All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.net.wanmo.common.zxing.QRCodeGenerate Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
package cn.net.wanmo.common.zxing;

import com.google.zxing.*;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

public class QRCodeGenerate {

    private static Logger logger = LoggerFactory.getLogger(QRCodeGenerate.class);


    /**
     * 默认编码
     */
    private String charset = "UTF-8";
    /**
     * 图片格式
     */
    private String formatName = "png";
    /**
     * 二维码尺寸
     */
    private int qrcodeSize = 300;
    /**
     * 二维码文件
     */
    private File qrcodeFile;
    /**
     * 二维码数据流
     */
    private OutputStream qrcodeOut;
    /**
     * LOGO尺寸
     */
    private int logoSize = 60;
    /**
     * LOGO文件
     */
    private File logoFile;
    /**
     * 是否压缩 logo
     */
    private boolean logoCompress = false;

    public QRCodeGenerate() {
        try {
            this.qrcodeFile = File.createTempFile("qrcode_", "." + this.formatName);
        } catch (Exception e) {

        }
    }


    /**
     * 默认编码
     */
    public QRCodeGenerate charset(String charset) {
        this.charset = charset;
        return this;
    }

    /**
     * 图片格式
     */
    public QRCodeGenerate formatName(String formatName) {
        this.formatName = formatName;
        return this;
    }

    /**
     * 图片格式
     */
    public QRCodeGenerate qrcodeSize(int qrcodeSize) {
        this.qrcodeSize = qrcodeSize;
        return this;
    }

    /**
     * 二维码文件
     */
    public QRCodeGenerate qrcodeFile(File qrcodeFile) {
        this.qrcodeFile = qrcodeFile;
        return this;
    }

    /**
     * 二维码数据流
     */
    public QRCodeGenerate qrcodeOut(OutputStream qrcodeOut) {
        this.qrcodeOut = qrcodeOut;
        return this;
    }

    /**
     * LOGO图片格式
     */
    public QRCodeGenerate logoSize(int logoSize) {
        this.logoSize = logoSize;
        return this;
    }

    /**
     * LOGO文件
     */
    public QRCodeGenerate logoFile(File logoFile) {
        this.logoFile = logoFile;
        return this;
    }

    /**
     * 是否压缩 LOGO
     */
    public QRCodeGenerate logoCompress(boolean logoCompress) {
        this.logoCompress = logoCompress;
        return this;
    }


    public static QRCodeGenerate build() {
        return new QRCodeGenerate();
    }

    /**
     * 生成二维码
     */
    public File generateOut(String data) {
        return generateOut2(data);
    }

    /**
     * 生成二维码
     */
    public File generateOut1(String data) {
        try {
            BitMatrix bitMatrix = generateBitMatrix(data);
            MatrixToImageWriter.writeToStream(bitMatrix, this.formatName, this.qrcodeOut);

            logger.info("二维码已生成并保存到: {}", qrcodeFile.getAbsolutePath());
        } catch (Exception e) {
            logger.error("二维码生成异常: " + e.getMessage(), e);
        }
        return qrcodeFile;
    }

    /**
     * 生成二维码
     */
    public File generateOut2(String data) {
        try {
            BufferedImage image = generateBufferedImage(data);
            ImageIO.write(image, this.formatName, this.qrcodeOut);

            logger.info("二维码已生成并保存到: {}", qrcodeFile.getAbsolutePath());
        } catch (Exception e) {
            logger.error("二维码生成异常: " + e.getMessage(), e);
        }
        return qrcodeFile;
    }


    /**
     * 生成二维码
     */
    public File generateFile(String data) {
        return generateFile2(data);
    }

    /**
     * 生成二维码
     */
    public File generateFile1(String data) {
        try {
            BitMatrix bitMatrix = generateBitMatrix(data);
            MatrixToImageWriter.writeToPath(bitMatrix, this.formatName, qrcodeFile.toPath());

            logger.info("二维码已生成并保存到: {}", qrcodeFile.getAbsolutePath());
        } catch (Exception e) {
            logger.error("二维码生成异常: " + e.getMessage(), e);
        }
        return qrcodeFile;
    }

    /**
     * 生成二维码
     */
    public File generateFile2(String data) {
        try {
            BufferedImage image = generateBufferedImage(data);
            ImageIO.write(image, this.formatName, this.qrcodeFile);

            logger.info("二维码已生成并保存到: {}", qrcodeFile.getAbsolutePath());
        } catch (Exception e) {
            logger.error("二维码生成异常: " + e.getMessage(), e);
        }
        return qrcodeFile;
    }

    /**
     * 二维码位图对象
     *
     * @param data 数据
     * @return 对象
     * @throws WriterException
     */
    public BitMatrix generateBitMatrix(String data) throws WriterException {
        Map hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, this.charset); // 设置字符编码
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 错误纠正级别
        hints.put(EncodeHintType.MARGIN, 1); // 二维码边距

        MultiFormatWriter writer = new MultiFormatWriter();
        BitMatrix bitMatrix = writer.encode(data, BarcodeFormat.QR_CODE, this.qrcodeSize, this.qrcodeSize, hints);

        return bitMatrix;
    }

    /**
     * 二维码位图对象
     *
     * @param data 数据
     * @return 对象
     * @throws WriterException
     */
    public BufferedImage generateBufferedImage(String data) throws WriterException {
        BitMatrix bitMatrix = generateBitMatrix(data);
        BufferedImage bufferedImage = toBufferedImage(bitMatrix);

        { // 添加 Logo
            addLogo(bufferedImage);
        }

        return bufferedImage;
    }


    /**
     * 获取 二维码中的内容
     *
     * @return 内容
     * @throws Exception
     */
    public String parse() {
        try {
            if (this.qrcodeFile == null || this.qrcodeFile.exists() == false) {
                return null;
            }

            BufferedImage image = ImageIO.read(this.qrcodeFile);

            BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            Hashtable hints = new Hashtable();
            hints.put(DecodeHintType.CHARACTER_SET, this.charset);

            Result result = new MultiFormatReader().decode(bitmap, hints);

            return result.getText();
        } catch (Exception e) {
            logger.error("二维码解析异常: " + e.getMessage(), e);
            return null;
        }
    }

    /**
     * 添加 Logo
     *
     * @param source 二维码源图
     */
    private void addLogo(BufferedImage source) {
        try {
            if (this.logoFile == null || this.logoFile.exists() == false) {
                return;
            }

            Image logoImage = ImageIO.read(this.logoFile);
            int width = logoImage.getWidth(null);
            int height = logoImage.getHeight(null);

            if (this.logoCompress) { // 压缩LOGO
                if (width > this.logoSize) {
                    width = this.logoSize;
                }
                if (height > this.logoSize) {
                    height = this.logoSize;
                }

                Image tempImage = logoImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
                BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(tempImage, 0, 0, null); // 绘制缩小后的图
                g.dispose();

                logoImage = tempImage;
            }

            { // 插入LOGO
                Graphics2D graph = source.createGraphics();
                int x = (this.qrcodeSize - width) / 2;
                int y = (this.qrcodeSize - height) / 2;

                graph.drawImage(logoImage, 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();
            }
        } catch (Exception e) {
            logger.error("二维码添加logo异常: " + e.getMessage(), e);
        }

    }

    /**
     * BitMatrix 转为 BufferedImage
     */
    private BufferedImage toBufferedImage(BitMatrix bitMatrix) {
        int width = bitMatrix.getWidth();
        int height = bitMatrix.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, bitMatrix.get(x, y) ? Color.BLACK.getRGB() : Color.WHITE.getRGB());
            }
        }
        return image;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy