springboot 生成二维码图片


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.MatrixToImageConfig;
import com.google.zxing.client.j2se.MatrixToImageWriter;
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.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 生成二维码图片
 *
 * @author Mr丶s
 * @date 2024/8/25 下午10:54
 * @description
 */
public class QRCodeGeneratorUtils {




    /**
     * 生成二维码图片
     *
     * @param content     二维码内容
     * @param width       二维码宽度
     * @param height      二维码高度
     * @param logoPath    中心 logo 路径,可为 null
     * @param bgImagePath 背景图片路径,可为 null
     * @return 二维码图片的字节数组
     * @throws Exception 异常信息
     */
    public static byte[] generateQRCodeImage(String content,
                                             int width,
                                             int height,
                                             String logoPath,
                                             String bgImagePath) {
        // 配置二维码的参数
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.MARGIN, 1);
        // 输出为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            // 生成二维码矩阵
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);


            // 将矩阵转为图片
            BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix, new MatrixToImageConfig());

            // 如果提供了背景图片,则将背景图片与二维码合成
            if (bgImagePath != null) {
                BufferedImage bgImage = ImageIO.read(new File(bgImagePath));
                qrImage = overlayImages(bgImage, qrImage);
            }

            // 如果提供了中心 logo,则将 logo 叠加在二维码中
            if (logoPath != null) {
                BufferedImage logoImage = ImageIO.read(new File(logoPath));
                qrImage = addLogoToQRCode(qrImage, logoImage);
            }

            ImageIO.write(qrImage, "png", outputStream);
        } catch (WriterException | IOException e) {
            throw new RuntimeException(e);
        }
        return outputStream.toByteArray();
    }

    /**
     * 将两个图片进行叠加
     *
     * @param bgImage 背景图片
     * @param qrImage 二维码图片
     * @return 叠加后的图片
     */
    private static BufferedImage overlayImages(BufferedImage bgImage, BufferedImage qrImage) {
        int width = Math.max(bgImage.getWidth(), qrImage.getWidth());
        int height = Math.max(bgImage.getHeight(), qrImage.getHeight());

        BufferedImage combined = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = combined.createGraphics();

        g.drawImage(bgImage, 0, 0, null);
        g.drawImage(qrImage, (width - qrImage.getWidth()) / 2, (height - qrImage.getHeight()) / 2, null);

        g.dispose();
        return combined;
    }

    /**
     * 为二维码添加 logo
     *
     * @param qrImage   二维码图片
     * @param logoImage logo 图片
     * @return 添加 logo 后的二维码图片
     */
    private static BufferedImage addLogoToQRCode(BufferedImage qrImage, BufferedImage logoImage) {
        Graphics2D g = qrImage.createGraphics();

        int logoWidth = qrImage.getWidth() / 5;
        int logoHeight = logoImage.getHeight() * logoWidth / logoImage.getWidth();

        int x = (qrImage.getWidth() - logoWidth) / 2;
        int y = (qrImage.getHeight() - logoHeight) / 2;

        g.drawImage(logoImage, x, y, logoWidth, logoHeight, null);

        // 设置圆角边框
        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
        g.setStroke(stroke);
        RoundRectangle2D.Float round = new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 20, 20);
        g.setColor(Color.WHITE);
        g.draw(round);

        g.dispose();
        return qrImage;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值