【问题标题】:PdfContentStreamEditor rotating image on PDF filePdfContentStreamEditor 在 PDF 文件上旋转图像
【发布时间】:2018-09-03 11:07:22
【问题描述】:

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

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

我尝试在几个 PDF 查看器(Sumatra PDF、Edge Browser 和 Adob​​e Acrobat)中打开文件,都显示出同样的怪异。

我想我有两个问题: a) PDF 文件如何从文件末尾仅包含 XMP 元数据进行如此更改? b) 如何使 iTextSharp 不产生此输出? (iTextSharp 似乎只在我添加/编辑内容时执行此操作,而不是在我仅删除 Javascript 或类似内容时执行此操作)


我用于 iTextSharp 的代码是此处帖子中的 PdfContentStreamEditor(逐字):https://stackoverflow.com/a/35915789/2535822
编辑 1>

好的..它似乎不是 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ÁÆ€
....

编辑 2>

【问题讨论】:

  • 我的PdfContentStreamEditor 班级可能有问题。不过,为了验证我需要有问题的 PDF。
  • 我有另一个 PDF,在输入代码时似乎也显示出“怪异”。我可以发送这个,因为它不包含我们的任何特权公司信息。如何最好地发送给您?我确实查看了 Adob​​e PDF 规范,因为我对 Write 方法在输出中放置一个空格/换行符感到惊讶(我期待一个完整的 1:1 写入)......但它似乎是有效的(尽管,如注意,我对PDF格式一无所知)
  • 如果其中没有特权信息,您可以简单地通过例如共享文件。公开的 Google 云端硬盘或投递箱共享。
  • 这里既是原件,又是通过 PdfContentStreamEditor 处理的(没有任何应该进行的编辑)。我只在第一页进行了 EditContent 调用,因此其他页面仍然正常。 drive.google.com/open?id=1KSXgoPgkUX9atCPQXDcx86T30xLBgJYJ
  • 您共享的文件似乎具有在某些情况下覆盖带有注释的页面的功能。此类功能可能对文档更改非常敏感。我会在接下来的几天里尝试更好地理解这个功能。

标签: c# pdf itext pdf-generation pdfstamper


【解决方案1】:

您确实在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 使用默认密码加密,并且
  • 使用 PdfStamper 在追加模式下编辑的 OP 使用与原始文件相同的密码对添加的内容进行加密。

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

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

【讨论】:

    【解决方案2】:

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

    您必须在显着位置提及 iText 并包含 iText 版权和 输出文件元数据中的 AGPL 许可证。

    【讨论】:

    • 好的,这个 iText / AGPL 元数据是否可能导致我看到的显示问题?它似乎确实以一堆标准 PDF 元素之类的东西结束... >/XObject>/字体>>>/Contents[405 0 R]>> endobj xref ..... 预告片 ] /上一页 2532558>> %iText-5.5.13 startxref 2545243 %%EOF
    • 元数据从不更改 PDF 的视觉表示。但是,我读到 (1) 您不太了解 ISO 32000,但是 (2) 您正在编辑内容流。这是一个矛盾。这就像对 PDF 说:我不是外科医生,也不是脑部专家,但我要为你做脑部手术。如果你想编辑内容流,你需要知道你在做什么。
    • @bruno 也许我错了……而且涉及的不仅仅是元数据。可以在此处找到原始和损坏的 PDF drive.google.com/open?id=1KSXgoPgkUX9atCPQXDcx86T30xLBgJYJ
    • 因为您在 AGPL 上下文中使用 iText,我们在哪里可以看到您的整个代码?也许在 GitHub 上的某个地方?我的意思是,您的文件显然是专有的,但您的代码不是。 (因为 AGPL)
    • @Amadee-van-gasse,我的整个代码由一个 Windows 窗体、一个来自 mkl 的 stackoverflow 帖子的 CS 文件和 itextsharp nuget 包组成。它尚未分发或可供我以外的任何人使用.. 除了吐出一个不稳定的页面 1 之外,它目前也没有做任何事情。正如您从 AGPL 中知道的那样,如果它没有被其他人使用或分发然后修改后的工作源代码不需要发布......但是如果我确实得到了一些工作,那么我会将它放在github上。如果没有,我会把它装箱,然后做其他事情。
    猜你喜欢
    • 1970-01-01
    • 2015-01-31
    • 2021-10-09
    • 2010-11-03
    • 2015-11-04
    • 2011-09-18
    • 2018-12-27
    • 2018-10-07
    • 1970-01-01
    相关资源
    最近更新 更多