使用itext java库复制时pdf文件大小大大增加

psp*_*psp 4 java pdf itext

我正在尝试使用 Java 中的 itextpdf 库将现有的 pdf 文件复制到一些新文件中。我使用的是 itextpdf 5.5.10 版本。我在两种方式上都面临着不同的问题:PDFStamper 和 PdfCopy。当我使用 PDFStamper 类时,我观察到新文件大小大幅增加,尽管没有添加任何新项目。这是代码片段:

    String currFile="C:\misc\pdffiles\AcroJS.pdf" ;
    String dest = "C:\misc\pdffiles\AcroJS_copy.pdf" ;
    PdfReader reader = new PdfReader(currFile) ;
    PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
    stamper.close() ;
    reader.close() ;
Run Code Online (Sandbox Code Playgroud)

一些观察结果是:7 MB(原始)到 13 MB(大约,新文件),116 KB > 119 KB(大约)

当我复制现有的 pdf 文件时,我期望文件大小大致相同。我无法弄清楚为什么尺寸会增加那么多。

我也尝试过 PdfCopy 类。我使用 PdfCopy 遵循了两种方法:

  1. 一页一页地复制。
  2. 在 pdfcopy 对象上调用 setMergeFields() 然后调用 pdfcopy.addDocument(reader) ;

但这两种方法的问题在于,它会丢弃 pdf 文件中的一些非内容元数据,因此新的 pdf 在由 Adob​​e reader 打开时会被破坏。例如我的 pdf 包含字典对象 PdfName.S 。在这种情况下,新创建的 pdf 文件只有 2KB(原始文件为 1.6 MB),这显然意味着没有任何内容复制到文档中,并且它已损坏。

我最初的要求很简单:将现有的pdf复制到新的pdf文件,不增加大小,不扔掉必要的项目。显然它不像复制、粘贴然后重命名。因为下一步我要对pdf内容进行一些处理。任何帮助都感激不尽。

操作系统:Windows 10 Pro Java:1.8.101 itext:5.5.10

谢谢

mkl*_*mkl 5

用于PdfStamper

你的代码

你的代码

PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
stamper.close() ;
Run Code Online (Sandbox Code Playgroud)

本质上是告诉 iText 复制原始 PDF,丢弃未使用的对象并使用 iText 的默认压缩设置

iText 的默认压缩设置包括使用压缩交叉引用和对象流(在 PDF 1.5 中引入),而是使用交叉引用表和单独压缩对象的旧技术。

另一方面,示例文件确实使用了这些技术。因此,它的压缩效果要好得多。

全压缩代码

您也可以告诉 iText 使用这些改进的压缩技术,如下所示:

PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.setFullCompression();

stamper.close();
Run Code Online (Sandbox Code Playgroud)

Stamping.java测试方法testStampAcroJSCompressed

这会导致文件大小小于 4 MB。

使用附加模式的代码

如果您想保持对象存储的原始方式,您可以使用追加模式,它以相同的方式复制原始文件并以所谓的增量更新的形式添加更改,如下所示:

PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream, '\0', true);

stamper.close();
Run Code Online (Sandbox Code Playgroud)

Stamping.java测试方法testStampAcroJSAppended

这会产生比原始文件稍大的文件。

用于PdfCopy

你观察到PdfCopy

正在丢弃一些非内容元数据

当然可以。PdfCopy旨在将页面从一个 PDF 复制到另一个 PDF,保持内容和注释不变,但忽略其他页面级和所有文档级信息。