可以根据需求是否实现下载到压缩文件中

参考地址:https://blog.csdn.net/Alian_1223/article/details/117332164

代码实现:

<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.datamatrix.encoder.SymbolShapeHint;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.apache.commons.lang3.StringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static java.util.Objects.nonNull;

public class QrCodeUtils {
    //黑色
    private static final int BLACK = 0xFF000000;
    //白色
    private static final int WHITE = 0xFFFFFFFF;
    //编码集
    private static final String CHARSET = "UTF-8";

    /**
     * @param content:二维码的内容
     * @param width:要生成的二维码的宽度
     * @param height:要生成的二维码的高度
     * @param fileName:文件的名称
     * @param imageType:文件的类型
     * @param filePath:文件的地址
     */
    public static String createImage(String logoFile,String content, int width, int height, String fileName, String imageType, String filePath) {
        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);//编码集
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//容错率
        hints.put(EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE);//生成的数据矩阵的形状
        try {
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            File file = new File(filePath, fileName + "." + imageType);
            bitMatrix = deleteWhite(bitMatrix);
            writeToFile(logoFile,bitMatrix, imageType, file);
            return filePath + File.separator + fileName + "." + imageType;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 清除白边
     *
     * @param matrix
     * @return
     */
    public static BitMatrix deleteWhite(BitMatrix matrix) {
        int[] rec = matrix.getEnclosingRectangle();
        int resWidth = rec[2];
        int resHeight = rec[3];
        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
        resMatrix.clear();
        for (int i = 0; i < resWidth; i++) {
            for (int j = 0; j < resHeight; j++) {
                if (matrix.get(i + rec[0], j + rec[1]))
                    resMatrix.set(i, j);
            }
        }
        return resMatrix;
    }

    /**
     * 写入二维码文件
     * @param matrix
     * @param format
     * @param file
     * @throws IOException
     */
    public static void writeToFile(String logoFileUrl,BitMatrix matrix, String format, File file) throws Exception {
        int width = matrix.getWidth();
        int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        if(StringUtils.isNotBlank(logoFileUrl)){
            File logoFile = new File(logoFileUrl);
            if (nonNull(logoFile) && logoFile.exists()) {
                // 构建绘图对象
                Graphics2D g = image.createGraphics();
                // 读取Logo图片
                BufferedImage logo = ImageIO.read(logoFile);
                // 开始绘制logo图片
                g.drawImage(logo, width * 2 / 5, height * 2 / 5, width * 2 / 10, height * 2 / 10, null);
                g.dispose();
                logo.flush();
            }
        }
        image.flush();
        if (!ImageIO.write(image, format, file)) {
            throw new IOException("Could not write an image of format " + format + " to " + file);
        }
    }

    public static void main(String[] args) throws Exception{
        FileOutputStream fos = new FileOutputStream("D:\\sxh\\imageFolder.zip");
        ZipOutputStream zos = new ZipOutputStream(fos);
        for(int i=0;i<3;i++){
            String qrCodeContent = "https://www.baidu.com";
            //二维码要生成的路径
            String qrCodeImagePath = "D:\\sxh";
            String logoPath = "C:\\Users\\86181\\Desktop\\2.png";
            //生成Alian.png的二维码图片(去除白边)
            String qrCodeUrl = createImage(logoPath,qrCodeContent, 240, 240, "qrCode_Alian", "png", qrCodeImagePath);
            //本地背景图片地址
            String backGroundUrl = "C:\\Users\\86181\\Desktop\\4.png";
            //最终合成图片的地址
            String imageName = "D:\\sxh\\"+i+".png";
            //图片上的标签绘制
            String title = i+"YJ-320581-02-004298";
            //合成图片
            String merge = ImageUtil.merge(backGroundUrl, qrCodeUrl, imageName, title);
            ZipEntry zipEntry = new ZipEntry(merge);
            zos.putNextEntry(zipEntry);

            FileInputStream fis = new FileInputStream(new File(merge));

            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, length);
            }

            fis.close();
            // Delete the original file
            new File(merge).delete();
        }
        zos.closeEntry();
        zos.close();
    }
}
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @program: CSDN
 * @description: 图片合成工具
 * @author: Alian
 * @create: 2021-05-29 11:11:11
 **/
public class ImageUtil {

    /**
     * 一些写死的参数,一般是不会变的,各自根据自己的模板进行调整即可
     * @param backGroundImageUrl
     * @param qrCodeUrl
     * @param imageName
     * @param title
     * @return
     */
    public static String merge(String backGroundImageUrl, String qrCodeUrl, String imageName, String title) {
        // 添加字体的属性设置
        Font font = new Font("黑体", Font.BOLD, 20);
        try {
            //加载背景图片(也就是模板图)
            BufferedImage backGroundImage = ImageIO.read(new File(backGroundImageUrl));
            //加载二维码图片(也就是需要合成到模板图上的图片)
            BufferedImage imageCode = ImageIO.read(new File(qrCodeUrl));
            //把背景图片当做为模板
            Graphics2D graphics = backGroundImage.createGraphics();
            //在模板上绘制图象(需要绘图的图片,左边距,上边距,图片宽度,图片高度,图像观察者)同一个模板一般是不会变的
            graphics.drawImage(imageCode, 65, 182, 240, 240, null);
            //设置字体
            graphics.setFont(font);
            //设置颜色
            graphics.setColor(Color.BLACK);
            //获取字体度量(字体度量是指对于指定字号的某种字体,在度量方面的各种属性)
            FontMetrics fontMetrics = graphics.getFontMetrics(font);
            //获取字体度量的宽度
            int textWidth = fontMetrics.stringWidth(title);
            //左边距=(模板图宽度-文字宽度)/2
            int widthX = (backGroundImage.getWidth() - textWidth) / 2;
            //g.drawString(title, 820, 2850);
            //绘制文字(内容,左边距,上边距),同一个模板上边距一般也是不变的
            graphics.drawString(title, widthX, 460);
            //完成模板修改
            graphics.dispose();
            //获取新文件的地址
            File outPutFile = new File(imageName);
            //生成新的合成过的用户二维码并写入新图片,指定类型为png
            ImageIO.write(backGroundImage, "png", outPutFile);
            //zip(outPutFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回给页面的图片地址(因为绝对路径无法访问)
        return imageName;
    }

    public static void zip(File file) {
        try {
//            File outputFile = new File("output.png");
//            ImageIO.write(image, "png", outputFile);
            FileOutputStream fos = new FileOutputStream("D:\\sxh\\imageFolder.zip");
            ZipOutputStream zos = new ZipOutputStream(fos);
            ZipEntry zipEntry = new ZipEntry(file.getName());
            zos.putNextEntry(zipEntry);
            FileInputStream fis = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) > 0) {
                zos.write(buffer, 0, length);
            }
            fis.close();
            zos.closeEntry();
            zos.close();
            // Delete the original file
            file.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}