You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中无损压缩图片到KB级 解决邮件内嵌图渲染慢问题

邮件内嵌图片压缩渲染优化问题

问题背景

  • Spring Boot项目中渲染带内嵌图片的邮件时,编辑器(Iframe)无法识别CID:***格式的图片链接
  • 现有方案将CID替换为base64编码的图片内容,可正常渲染,但单张10Mb或5-10张图片时渲染耗时可达10秒(邮件内容存储在MongoDB中)
  • 需求:实现图片压缩+尺寸调整,适配编辑器展示,降低渲染耗时

原有CID替换实现代码

private String processInlineHtmlImages(String htmlContent, MimeMessageParser parser, String messageId) throws IOException {
  Collection<String> contentIds = parser.getContentIds();
  if (!CollectionUtils.isEmpty(contentIds)) {
    for (Iterator<String> contentId = contentIds.iterator(); contentId.hasNext();) {
      String cid = contentId.next();
      String imageContentId = "cid:" + cid;
      if (htmlContent.contains(imageContentId)) {
        DataSource contentIdbyteArray = parser.findAttachmentByCid(cid);
        String imageType = contentIdbyteArray.getContentType() != null ? contentIdbyteArray.getContentType() : "jpg";
        if (contentIdbyteArray != null) {
          ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
          try {
            IOUtils.copy(contentIdbyteArray.getInputStream(), outputStream);
          }
          catch (IOException e) {
            logger.error("CCM-MessageID: {} exception while processing inline image", messageId);
          }
          byte[] bytes = outputStream.toByteArray();
          // Resize the image if its greater then 1Mb
          if (bytes.length > 1048576) {
                // Compress code should be here if size of bytes more than 1Mb
          }
          StringBuilder imgSrc = new StringBuilder();
          imgSrc.append("data:image/" + imageType + ";base64,");
          imgSrc.append(Base64.getEncoder().encodeToString(bytes));

          // This will replace the html inline image cid to its bytes
          htmlContent = htmlContent.replaceAll(imageContentId, imgSrc.toString());
        }
      }
    }
    return htmlContent;
  }
  return null;
}

优化方案

工具选型

使用Java生态常用的Thumbnails图片处理库,原生支持等比例尺寸调整、画质压缩,API简单易用,适配JPG、PNG等主流图片格式。

压缩逻辑实现

在原有代码的压缩逻辑预留位置,加入如下代码即可实现尺寸适配+压缩:

// 导入对应类:import net.coobird.thumbnailator.Thumbnails;
ByteArrayInputStream compressInput = new ByteArrayInputStream(bytes);
ByteArrayOutputStream compressOutput = new ByteArrayOutputStream();
Thumbnails.of(compressInput)
        // 按编辑器最大展示宽度等比缩放,高度自适应,避免图片变形
        .width(1200)
        // 压缩质量设置为0.8,可根据实际清晰度需求调整,取值范围0.0-1.0
        .outputQuality(0.8f)
        // 保持原有图片格式
        .outputFormat(imageType)
        .toOutputStream(compressOutput);
// 替换为压缩后的字节数组
bytes = compressOutput.toByteArray();

优化注意点

  • 若使用PNG格式带透明通道的图片,不要强制转换为JPG格式,避免透明背景变为黑色
  • 可根据业务需求调整最大宽度和压缩质量参数,平衡清晰度和文件体积
  • 若对压缩后体积有严格要求,可增加循环判断逻辑,调整压缩参数直到体积符合阈值要求

内容的提问来源于stack exchange,提问作者Shrey Soni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:15:05