iText 不会从 PDF 文档的 /Pages 复制资源字典

iText does not copy resources dictionary from /Pages for a PDF Document

我有一个 Pdf,它的字体存储在文档的 /Pages 级别的 /Resources 字典中,以便每个页面都可以重复使用它们。这似乎实现了两件事:当然可以正确显示,而且文件大小更小。当使用 iText 从这个 Pdf 复制页面时,我注意到,无论使用更高级别还是更低级别的函数(例如 PdfPage 的 copyTo 或 copyFormAsXObject),生成的 Pdf 都没有特征 - 资源而是存储在每个个人页面。

是否有特殊原因导致在进行页面复制时不遵守此规定?

此外,我自己尝试这样做,但似乎没有任何方法可以将资源放在文档的页面上。我可以使用 PdfPages 上的 .put 方法对单个页面执行此操作,但是对于 PdfDocument,似乎没有等效项。有没有一种方法可以使用 iText 创建具有此结构的 PdfDocument?

您不必担心 PDF 会膨胀。资源作为间接对象添加到资源字典中。这意味着资源字典将保留对实际资源对象的引用,并且不需要将其嵌入到字典中。这是 PDF 的 /Pages 条目:

3 0 obj
<<
    /Type /Pages
    /Count 3
    /Kids [5 0 R 13 0 R 23 0 R ]
    /Resources <<
        /Font <<
            /FAAAAH 7 0 R
            /FAAABG 16 0 R
        >>
        /ExtGState <<
            /GS1 15 0 R
            /GS2 21 0 R
            /GS3 25 0 R
        >>
    >>
>>

“/FAAAAH 7 0 R”行表示字体 FAAAAH 是对象 #7。如您所见,资源字典仅保留对字体对象的引用 (7 0 R)。实际字体对象位于 PDF 中的其他位置。每个 PDF reader 和解析器都知道如何访问对象 #7.

如果您在复制或合并时遇到膨胀,那么 PDF 可能包含该字体两次而不是一次,并且有两个引用。 /Resources 的位置与文件的膨胀没有任何关系,它是增加膨胀的 PDF 内部的内容。

您可以在 iText 中通过 运行 智能模式下的 PdfWriter 解决这个问题:

pdfWriter.setSmartMode();

我们将研究为什么 iText 不复制继承。