springboot生成海报

 

package com.beauty.common.utils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * 在图片上生成二维码response前端
 */
public class QrCodeInnerImageUtil {

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

    /***
     * @param content 二维码中保存的内容
     * @param response http响应对象
     * 在一张背景图上添加二维码
     */
    public static String drawString(String content, Boolean isBase64, HttpServletResponse response) throws Exception {
        BufferedImage image = addWater(content);
        Graphics2D gd = image.createGraphics();
        // 设置扛锯齿,字体更清晰
        gd.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        // 设置文字颜色
        gd.setColor(new Color(128, 153, 101));
        int fontSize = 35;
        // 创建字体对象
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        ClassLoader classLoader = QrCodeInnerImageUtil.class.getClassLoader();
        InputStream fontStream = classLoader.getResourceAsStream("fonts/SIMHEI.TTF");
        Font font = Font.createFont(Font.TRUETYPE_FONT, fontStream).deriveFont(Font.BOLD, fontSize);
        ge.registerFont(font);

        // 设置字体
        gd.setFont(font);

        //获取图片宽度
        int width = image.getWidth();

        //计算文字居中X轴坐标位置
        FontMetrics metrics = gd.getFontMetrics();
        String text1 = "邀请好友成功";
        String text2 = "可获得古法艾灸免单";
        String text3 = "券";
        String text4 = "1次";
        //文字所占宽度
        int textWidth1 = metrics.stringWidth(text1);
        int textWidth2 = metrics.stringWidth(text2);
        int textWidth3 = metrics.stringWidth(text3);

        int x1 = (width - textWidth1) / 2;
        int x2 = (width - textWidth2) / 2;
        int x3 = (width - textWidth3) / 2 - fontSize;
        int x4 = x3 + fontSize;

        int y1 = 640;
        int y2 = 640 + 50;
        int y3 = 640 + 100;

        //// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
        gd.drawString(text1, x1, y1);
        gd.drawString(text2, x2, y2);
        gd.drawString(text3, x3, y3);

        //重新设置字体字号、颜色
        gd.setColor(new Color(69, 89, 43));
        gd.setFont(font.deriveFont(Font.BOLD, fontSize + 5)); // 修改字体大小
        gd.drawString(text4, x4, y3);

        //释放画笔资源
        gd.dispose();

        if (isBase64) {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            // 将图像写入输出流
            ImageIO.write(image, "png", outputStream);
            // 将输出流转换为字节数组
            byte[] bytes = outputStream.toByteArray();
            // 关闭输出流
            IoUtil.close(outputStream);
            // 将字节数组转换为Base64编码的字符串
            String base64Image = "data:image/png;base64," + Base64.encode(bytes);
            return base64Image;

        } else {
            // 输出图片
            ServletOutputStream outputStream = response.getOutputStream();
            ImageIO.write(image, "png", outputStream);
            outputStream.flush();
            outputStream.close();

        }

        return null;
    }

    /***
     * 在一张背景图上添加二维码
     */
    public static BufferedImage addWater(String content) throws Exception {
        Image srcImg = getImage("https://oss.benshutech.com/websites/mianhuatang-mp/naiwan/components/inviteQrcode.png");
        //获取图片的宽
        int srcImgWidth = srcImg.getWidth(null);
        //获取图片的高
        int srcImgHeight = srcImg.getHeight(null);
        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bufImg.createGraphics();
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        // 使用工具类生成二维码
        QrConfig qrConfig = new QrConfig();
        qrConfig.setWidth(150);
        qrConfig.setHeight(150);
        qrConfig.setMargin(0);
        qrConfig.setErrorCorrection(ErrorCorrectionLevel.H);
        BufferedImage image = QrCodeUtil.generate(content, qrConfig);
        //将小图片绘到大图片上,500,300 .表示你的小图片在大图片上的位置。
        g.drawImage(image, 225, 420, null);
        //设置颜色。
        g.setColor(Color.WHITE);
        g.dispose();
        return bufImg;
    }

    /**
     * 获取图片
     *
     * @param url 图片地址
     * @return
     * @throws IOException
     */
    public static Image getImage(String url) throws IOException {
        // 图片的URL
        URL imageUrl = new URL(url);
        // 读取图片到BufferedImage
        BufferedImage bufferedImage = ImageIO.read(imageUrl);
        // 检查是否成功读取
        if (bufferedImage == null) {
            logger.error("图片资源加载失败!url={}", url);
        }
        return bufferedImage;
    }
}

 

pom.xml文件

        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <excludes>
                    <exclude>fonts/**</exclude>
                </excludes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <includes>
                    <include>fonts/**</include>
                </includes>
            </resource>
        </resources>

 

使用方法

String base64 = QrCodeInnerImageUtil.drawString(code, isBase64, response);

 

字体文件需要自己放在resources/fonts

 

posted @ 2024-08-03 09:55  程序员小艺  阅读(22)  评论(0编辑  收藏  举报