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

com.github.xiaoyuge5201.qrcode.QrCodeUtil Maven / Gradle / Ivy

There is a newer version: 1.3.5
Show newest version
package com.github.xiaoyuge5201.qrcode;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageConfig;
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 javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码 工具类
 */
public class QrCodeUtil {

    /**
     * 生成带图片的二维码(到destImagePath指向的File)
     *
     * @param content         二维码的内容
     * @param width           二维码的宽度(px)
     * @param height          二维码的高度(px)
     * @param embeddedImgPath 被镶嵌的图片的地址(null表示不带logo图片)
     * @param destImagePath   生成二维码图片的地址
     * @return 生成的二维码文件path
     * @throws IOException     IOException
     * @throws WriterException WriterException
     */
    public static String QREncode(String content, int width, int height, String embeddedImgPath, String destImagePath) throws IOException, WriterException {
        File dest = getFile(destImagePath);
        // 图像类型
        String format = "jpg";
        Map hints = new HashMap<>(4);
        //设置UTF-8, 防止中文乱码
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //设置二维码四周白色区域的大小
        hints.put(EncodeHintType.MARGIN, 1);
        //设置二维码的容错性
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //画二维码,记得调用multiFormatWriter.encode()时最后要带上hints参数,不然上面设置无效
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        //开始画二维码
        MatrixToImageWriter.writeToPath(bitMatrix, format, dest.toPath());
        if (null != embeddedImgPath) {
            MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
            BufferedImage bufferedImage = LogoMatrix(MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig), embeddedImgPath);
            //输出带logo图片
            ImageIO.write(bufferedImage, format, dest);
        }
        return destImagePath;
    }

    /**
     * 生成带图片的二维码(到outputStream流)
     *
     * @param content         二维码的内容
     * @param width           二维码的宽度(px)
     * @param height          二维码的高度(px)
     * @param embeddedImgPath 被镶嵌的图片的地址(null表示不带logo图片)
     * @param outputStream    生成二维码图片的地址
     * @return 生成的二维码文件path
     * @throws IOException     IOException
     * @throws WriterException WriterException
     */
    public static void QREncode(String content, int width, int height, String embeddedImgPath, OutputStream outputStream) throws IOException, WriterException {
        // 图像类型
        String format = "jpg";
        Map hints = new HashMap<>(4);
        //设置UTF-8, 防止中文乱码
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        //设置二维码四周白色区域的大小
        hints.put(EncodeHintType.MARGIN, 1);
        //设置二维码的容错性
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        //画二维码,记得调用multiFormatWriter.encode()时最后要带上hints参数,不然上面设置无效
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
        //开始画二维码
        MatrixToImageConfig matrixToImageConfig = new MatrixToImageConfig(0xFF000001, 0xFFFFFFFF);
        BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix, matrixToImageConfig);
        if (null != embeddedImgPath) {
            bufferedImage = LogoMatrix(bufferedImage, embeddedImgPath);
        }
        //输出带logo图片
        boolean result = ImageIO.write(bufferedImage, format, outputStream);
    }

    /**
     * 识别二维码内容信息
     *
     * @param file 二维码图片文件
     * @return 二维码内容
     * @throws NotFoundException NotFoundException
     * @throws IOException       IOException
     */
    public static String QRReader(File file) throws NotFoundException, IOException {
        BufferedImage bufferedImage;
        bufferedImage = ImageIO.read(file);
        if (bufferedImage == null) {
            return null;
        }
        String data = decodeQrCode(bufferedImage);
        bufferedImage.flush();
        return data;
    }

    /**
     * 识别二维码内容信息
     *
     * @param is 二维码图片文件流
     * @return 二维码内容
     * @throws NotFoundException NotFoundException
     * @throws IOException       IOException
     */
    public static String QRReader(InputStream is) throws NotFoundException, IOException {
        BufferedImage bufferedImage;
        bufferedImage = ImageIO.read(is);
        if (bufferedImage == null) {
            return null;
        }
        String data = decodeQrCode(bufferedImage);
        bufferedImage.flush();
        return data;
    }

    // ---------------------------------------------------以下为辅助方法、辅助类-----------------------------------------

    /**
     * 获取文件(顺带创建文件夹,如果需要的话)
     *
     * @param filePath 文件path
     * @return 文件对象
     */
    private static File getFile(String filePath) {
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            boolean result = file.getParentFile().mkdirs();
        }
        return file;
    }

    /**
     * 二维码添加logo
     *
     * @param matrixImage     源二维码图片
     * @param embeddedImgPath logo图片地址
     * @return 返回带有logo的二维码图片
     */
    private static BufferedImage LogoMatrix(BufferedImage matrixImage, String embeddedImgPath) throws IOException {
        /**
         * 读取二维码图片,并构建绘图对象
         */
        Graphics2D g2 = matrixImage.createGraphics();
        int matrixWidth = matrixImage.getWidth();
        int matrixHeigh = matrixImage.getHeight();
        /**
         * 读取Logo图片
         */
        File logoFile = getFile(embeddedImgPath);
        BufferedImage logo = ImageIO.read(logoFile);
        // 开始绘制图片
        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;
    }

    /**
     * 识别二维码内容信息
     * 二维码图片信息BufferedImage
     *
     * @param image
     * @return 二维码内容
     * @throws NotFoundException NotFoundException
     */
    private static String decodeQrCode(BufferedImage image) throws NotFoundException {
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        HashMap hints = new HashMap<>(4);
        hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
        Result result = new MultiFormatReader().decode(bitmap, hints);
        return result.getText();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy