java生成二维码添加指定文字logo,通过流将zip文件传回前端

@Override
public void getQRCodeAsZip(String garbageRoomId, HttpServletResponse response) throws IOException {
    //根据roomid在MgtGarbageRoomWeightDeviceEntity中查找对应的imei
    LambdaQueryWrapper<MgtGarbageRoomWeightDeviceEntity> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(MgtGarbageRoomWeightDeviceEntity::getFkGarbageRoomId, garbageRoomId);
    List<MgtGarbageRoomWeightDeviceEntity> list = this.list(wrapper);
    String imei = new String();
    for (MgtGarbageRoomWeightDeviceEntity mgtGarbageRoomWeightDeviceEntity : list) {
        imei = mgtGarbageRoomWeightDeviceEntity.getImei();
    }
    //如果imei为空,则代表该条数据的imei的信息还未录入
    if (StringUtils.isBlank(imei)) {
        throw new RenException("信息还未录入");
    }
    //设置请求头
    response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode("二维码", "UTF-8") + ".zip\"");
    response.setHeader("Content-Type", "application/zip");
    //设置二维码的内容和logo内容
    String baseUrlTemplate = "******";
    String[] qrTexts = {"***", "***", "***"};

    ByteArrayOutputStream zipOut = new ByteArrayOutputStream();
    ZipOutputStream zip = new ZipOutputStream(zipOut);
    try {
        for (int i = 0; i < 3; i++) {
            String url = String.format(baseUrlTemplate, garbageRoomId, imei) + i;

            BufferedImage qrCodeWithText = createQRCodeWithText(url, 200, 200, qrTexts[i]);
            ByteArrayOutputStream pngOut = new ByteArrayOutputStream();
            ImageIO.write(qrCodeWithText, "PNG", pngOut);
            //设置压缩包内二维码名字
            ZipEntry zipEntry = new ZipEntry("QRCode_" + qrTexts[i] + ".png");
            zip.putNextEntry(zipEntry);
            zip.write(pngOut.toByteArray());
            zip.closeEntry();
        }
    } catch (Exception e) {
        //自定义异常
        throw new RenException("下载附件失败", e);
    } finally {
        zip.close();
    }

    IOUtils.copy(new ByteArrayInputStream(zipOut.toByteArray()), response.getOutputStream());
}

public static BufferedImage createQRCodeWithText(String content, int width, int height, String text) throws Exception {
    Map<EncodeHintType, Object> hints = new HashMap<>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

    QRCodeWriter qrCodeWriter = new QRCodeWriter();
    BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics = (Graphics2D) image.getGraphics();
    //消除文字锯齿
    graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    graphics.setColor(Color.WHITE);
    graphics.fillRect(0, 0, width, height);

    // Draw text
    // 设置字体颜色和字体
    graphics.setColor(new Color(230, 132, 73));
    graphics.setFont(new Font("SansSerif", Font.BOLD, 18));
    FontMetrics metrics = graphics.getFontMetrics(graphics.getFont());
    // 计算文本的位置使其在图片中居中
    int x = (width - metrics.stringWidth(text)) / 2;
    int y = ((height - metrics.getHeight()) / 2) + metrics.getAscent();
    // 在图片中添加文本
    graphics.drawString(text, x, y - 5);

    // Draw QR Code
    for (int xi = 0; xi < width; xi++) {
        for (int yi = 0; yi < height; yi++) {
            if (xi < x || xi > (x + metrics.stringWidth(text)) || yi < (y - metrics.getHeight()) || yi > y) {
                if (bitMatrix.get(xi, yi)) {
                    image.setRGB(xi, yi, Color.BLACK.getRGB());
                } else {
                    image.setRGB(xi, yi, Color.WHITE.getRGB());
                }
            }
        }
    }

    graphics.dispose();
    return image;
}

pom文件添加    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>core</artifactId>
        <version>3.4.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.zxing</groupId>
        <artifactId>javase</artifactId>
        <version>3.4.1</version>
    </dependency>

使用postman测试,直接生成的是乱码,需要将结果下载下来后查看

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = (Graphics2D) image.getGraphics();

这两行代码是Java中用于创建和操作图像的代码片段。

第一行代码创建了一个BufferedImage对象,它是Java中表示图像的类。BufferedImage是一个带有可访问的图像数据缓冲区的图像类,可以进行像素级别的读取和操作。

在该代码中,使用BufferedImage类的构造函数创建了一个新的BufferedImage对象,并传入了三个参数:widthheightBufferedImage.TYPE_INT_RGB。其中,widthheight是指定图像的宽度和高度,而BufferedImage.TYPE_INT_RGB代表图像的颜色模型为RGB。

第二行代码获取了刚创建的BufferedImage对象的图形上下文,并将其转换为Graphics2D对象。通过image.getGraphics()方法可以获得一个可用于绘制和操作图像的Graphics2D对象。

Graphics2D是Java中用于进行2D图形操作的类,它是Graphics类的子类。通过获取到的Graphics2D对象,你可以在图像上进行各种图形绘制、颜色填充、文本渲染等操作。

总的来说,这两行代码创建了一个指定大小的空白图像,并获取了一个可以对该图像进行绘制和操作的Graphics2D对象。

QRCodeWriter qrCodeWriter = new QRCodeWriter(); BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

这两行代码是使用ZXing库(一个开源的条形码和二维码生成工具)来生成QR码的代码。

第一行代码创建了一个QRCodeWriter对象,它是ZXing库中用于生成QR码的类。通过实例化QRCodeWriter对象,我们可以使用其提供的方法来生成QR码。

第二行代码使用qrCodeWriter对象的encode()方法来生成QR码的位矩阵(BitMatrix对象)。该方法接受五个参数:contentBarcodeFormat.QR_CODEwidthheighthints

  • content是要编码为QR码的内容,通常是一个字符串。
  • BarcodeFormat.QR_CODE指定生成的条码类型为QR码。
  • widthheight指定QR码的宽度和高度(以像素为单位)。
  • hints是一个可选的参数,可以用来设置QR码生成的一些附加选项,例如纠错级别、编码字符集等。

qrCodeWriter.encode()方法将根据提供的参数生成QR码的位矩阵,并将其赋值给bitMatrix变量。

总体上,这两行代码使用ZXing库创建了一个QRCodeWriter对象,并使用该对象生成QR码的位矩阵。后续可以通过处理bitMatrix对象来输出显示QR码或进行其他操作。

for (int xi = 0; xi < width; xi++) {

for (int yi = 0; yi < height; yi++) {

if (xi < x || xi > (x + metrics.stringWidth(text)) || yi < (y - metrics.getHeight()) || yi > y) {

if (bitMatrix.get(xi, yi)) {

image.setRGB(xi, yi, Color.BLACK.getRGB()); }

else { image.setRGB(xi, yi, Color.WHITE.getRGB()); } } } }

这段代码是用于将生成的 QR 码位矩阵绘制到图像上的代码。

外层循环 for (int xi = 0; xi < width; xi++) 遍历图像的宽度,内层循环 for (int yi = 0; yi < height; yi++) 遍历图像的高度。

接下来是一个条件判断语句 if,判断当前坐标 (xi, yi) 是否在要绘制 QR 码的范围之外。判断的条件如下:

  • xi < x:坐标 xi 小于起始绘制点的横坐标 x
  • xi > (x + metrics.stringWidth(text)):坐标 xi 大于起始绘制点的横坐标加上文本的宽度。
  • yi < (y - metrics.getHeight()):坐标 yi 小于起始绘制点的纵坐标减去文本的高度。
  • yi > y:坐标 yi 大于起始绘制点的纵坐标。

如果以上条件都满足,则进入内部的 if 分支。在内部的 if 分支中,首先通过 bitMatrix.get(xi, yi) 方法判断 QR 码位矩阵中的对应位置是否为黑色(即为 true),如果是,则使用 image.setRGB(xi, yi, Color.BLACK.getRGB()) 将图像的对应位置设置为黑色。否则,将图像的对应位置设置为白色,即 image.setRGB(xi, yi, Color.WHITE.getRGB())

通过这段代码,可以将生成的 QR 码位矩阵绘制到图像上,并根据条件判断来决定绘制位置的颜色。未满足条件的位置将被设为白色,满足条件的位置将被设为黑色,最终生成一个带有 QR 码的图像。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值