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

PDFBox转Tiff内存溢出,如何压缩PDF中的JPEG图片?

解决JPEG添加到PDF后转Tiff内存溢出问题

你遇到的问题很典型——大尺寸JPEG直接加入PDF后,转Tiff时会因为内存占用过高抛出OutOfMemory异常。我们可以从图片预处理压缩和Tiff转换参数优化两个方向来解决,下面是具体的实现方案:

方案一:添加图片到PDF前压缩JPEG

在将JPEG转为PDImageXObject之前,先对图片进行压缩(调整尺寸或降低质量),这样能从源头减少内存占用。这里推荐两种实现方式:

用Thumbnails库压缩(简单易用)

首先确保引入依赖(Maven示例):

<dependency>
    <groupId>net.coobird</groupId>
    <artifactId>thumbnailator</artifactId>
    <version>0.4.19</version>
</dependency>

修改你的图片添加代码:

import net.coobird.thumbnailator.Thumbnails;
import java.io.ByteArrayOutputStream;

// 先压缩图片:可按需调整尺寸和质量
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Thumbnails.of(imagePath)
        .size(1920, 1080) // 设置目标分辨率,比如1080P
        .outputQuality(0.7) // 图片质量(0.0-1.0,数值越低压缩率越高)
        .outputFormat("jpeg")
        .toOutputStream(baos);

// 用压缩后的字节流创建PDImageXObject
PDImageXObject image = PDImageXObject.createFromByteArray(doc, baos.toByteArray(), "compressed-image");
PDPage page = new PDPage(new PDRectangle(image.getWidth(), image.getHeight()));
doc.addPage(page);

try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
    contents.drawImage(image, 0, 0);
} // try-with-resources会自动关闭流,无需手动调用close()

用JDK自带ImageIO压缩(无需额外依赖)

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import javax.imageio.IIOImage;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.util.Iterator;

// 读取原图片
BufferedImage originalImage = ImageIO.read(new File(imagePath));

// 配置JPEG压缩参数
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = writers.next();
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(0.7f); // 设置压缩质量

// 将压缩后的图片写入字节流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
writer.setOutput(ImageIO.createImageOutputStream(baos));
writer.write(null, new IIOImage(originalImage, null, null), param);
writer.dispose();

// 创建PDImageXObject并添加到PDF
PDImageXObject image = PDImageXObject.createFromByteArray(doc, baos.toByteArray(), "compressed-image");
PDPage page = new PDPage(new PDRectangle(image.getWidth(), image.getHeight()));
doc.addPage(page);

try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
    contents.drawImage(image, 0, 0);
}

方案二:优化PDF转Tiff的渲染参数

如果不想修改原图片,也可以在转Tiff时降低渲染分辨率、缩小图片尺寸,减少BufferedImage的内存占用:

修改你的PDF转Tiff代码:

document = PDDocument.load(new File(pdfFilename));
PDFRenderer pdfRenderer = new PDFRenderer(document);
BufferedImage[] images = new BufferedImage[document.getNumberOfPages()];

for (int i = 0; i < document.getNumberOfPages(); i++) {
    // 两种优化方式选其一:
    // 方式1:降低渲染DPI(默认通常是300,设为96能大幅减少内存)
    images[i] = pdfRenderer.renderImageWithDPI(i, 96, ImageType.RGB);
    // 方式2:设置缩放比例(比如缩到原尺寸的50%)
    // images[i] = pdfRenderer.renderImage(i, 0.5f);
}

// 后续将BufferedImage写入Tiff的代码...

你可以根据实际需求选择方案:如果需要保留图片清晰度,优先调整转Tiff的渲染参数;如果PDF本身也需要更小的体积,推荐先压缩图片再添加到PDF。

内容的提问来源于stack exchange,提问作者Divya Neelaiah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:12:53