PdfContentStreamEditor 在 PDF 文件上旋转图像

PdfContentStreamEditor rotating image on PDF file

我希望这是一个简单的问题。 我正在尝试使用 iTextSharp 修改一些 PDF 文件,但是 iTextSharp 放在文件末尾的 XMP 元数据似乎破坏了 PDF 文件的布局(而且我不太熟悉 PDF 格式完全明白为什么)。

您可以从上面的两个图像中看到文档似乎已被旋转。然而,从将 PDF 文件视为二进制差异来看,唯一不同的似乎是文件末尾的一些 XMP 元数据

我试过在多个 PDF 查看器(Sumatra PDF、Edge 浏览器和 Adob​​e Acrobat)中打开这些文件,但都显示出同样的怪异现象。

我想我有两个问题: a) PDF 文件如何从仅在文件末尾具有 XMP 元数据而发生如此大的变化? b) 如何让 iTextSharp 不产生这个输出? (iTextSharp 似乎只在我 Add/Edit 内容时执行此操作,而不是如果我只是删除 Javascript 或类似内容)

<编辑 1>
我用于 iTextSharp 的代码是 post 中的 PdfContentStreamEditor(逐字):

<编辑 2>
好的.. 它似乎不是 XMP 元数据。我通过使用摆脱了它:

pdfStamper.XmpMetadata = new byte[0];

但是文件末尾仍然有一堆额外的数据

2 0 obj
<</Producer(PDFCreator 2.5.2.5233; modified using iTextSharp’ 5.5.13 ©2000-2018 iText Group NV \(AGPL-version\))/CreationDate(D:20171206173510+10'30')/ModDate(D:20180325144710+11'00')/Title(þÿ
endobj
404 0 obj
<</Length 0/Type/Metadata/Subtype/XML>>stream

endstream
endobj
405 0 obj
<</Length 3638/Filter/FlateDecode>>stream
xœÍZmÅ/6ÒZ2ÁÆ€
....

我可以回答你的第二个问题。 您尝试删除的元数据不应被删除。您正在使用的 AGPL 版本的 DLL 将添加该元数据,无论您对代码做什么。您将无法使用 iText 删除它,因为它直接违反了他们的许可条款。 请参考:https://itextpdf.com/AGPL

You must prominently mention iText and include the iText copyright and AGPL license in output file metadata.

您确实发现了我在 this answer 中使用的 PdfContentStreamEditor 中的错误,而另一个问题需要知道如何禁用 iText 的特殊功能或怪癖(视情况而定) .

内容轮换

这部分处理OP提供的示例文档PHA-Pro 8 - File.pdf中内容的旋转。

正如您自己所见,旋转问题似乎与相关页面的页面旋转不是 0 的事实有关。

事实上,iText PdfStamper 有一个功能,在旋转页面的情况下自动旋转添加,适用于 OverContentUnderContent。如果您想向页面添加直立内容而无需自己应用旋转以使其直立,则此功能会非常方便。但是,在 PdfContentStreamEditor 的情况下,我们从现有内容中收到的所有坐标都已经考虑了适用的旋转。

因此,我们需要禁用此功能。可以使用 PdfStamper 属性 RotateContents:

using (PdfReader pdfReader = new PdfReader(source))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileStream(dest, FileMode.Create, FileAccess.Write), (char)0, true))
{
    pdfStamper.RotateContents = false;
    PdfContentStreamEditor editor = new PdfContentStreamEditor();

    for (int i = 1; i <= pdfReader.NumberOfPages; i++)
    {
        editor.EditPage(pdfStamper, i);
    }
}

文本加扰

这部分处理OP提供的示例文档AS62061-2006.pdf中的文本加扰。

您在 PdfContentStreamEditor 中发现了一个错误。它的 Write 方法包含这个循环:

foreach (PdfObject pdfObject in operands)
{
    pdfObject.ToPdf(canvas.PdfWriter, canvas.InternalBuffer);
    canvas.InternalBuffer.Append(operands.Count > ++index ? (byte) ' ' : (byte) '\n');
}

应该是

foreach (PdfObject pdfObject in operands)
{
    pdfObject.ToPdf(null, canvas.InternalBuffer);
    canvas.InternalBuffer.Append(operands.Count > ++index ? (byte) ' ' : (byte) '\n');
}

如果将 PdfWriter 提供给 PdfStringToPdf 方法并且 PdfWriter 使用加密,则字符串内容将被加密。但是这里的字符串被写入流,在这种情况下,不是必须加密单个字符串,而是最终加密整个流。

这适用于 OP 提供的 PDF,因为

  • PDF 使用默认密码加密,
  • OP 在附加模式下使用 PdfStamper 编辑,使用与原始文件相同的密码加密添加内容。

使用原始代码,结果如下所示:

使用固定代码,它看起来像这样: