从 pdf 获取注释以添加到另一个文档

Get annotation from a pdf to add to another document

我正在使用 iTextSharp 5.0 版。

对于我的项目,我需要使用 pdfWriter 将我的 pdf 文档复制到另一个 pdf 文档中。我不能使用 pdfCopy 或 pdfStamper。

所以在这个操作过程中所有的注释都丢失了。

首先,我开始寻找如何在 adobe 上获取如下所示的“铅笔评论绘图标记”的注释 reader UI:

对于我的测试,我使用的是带有我自己添加的绘图标记的 pdf 文档:https://easyupload.io/3c6i1g

我找到了获取注释字典的方法:

Dim pdfReader As New PdfReader(pdfPath)
Dim page As PdfDictionary = pdfReader.GetPageN(0)
Dim annots As PdfArray = page.GetAsArray(PdfName.ANNOTS)
If annots IsNot Nothing Then
    For i = 0 To annots.Size - 1
        Dim annotDict As PdfDictionary = annots.GetAsDict(i)
        Dim annotContents As PdfString = annotDict.GetAsString(PdfName.CONTENT)
        Dim annotSubtype As PdfString = annotDict.GetAsString(PdfName.SUBTYPE)
        Dim annotName As PdfString = annotDict.GetAsString(PdfName.T)

    Next
End If

当循环解析我的注释时,annotName 变量 returns 我的名字,所以我肯定会解析我正在寻找的注释,但 annotSubtype 等于 Nothing,这怎么可能?根据 12.5.2 table 1666 (https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf) 部分的 pdf 规范,子类型参数是必需的,所以这是否意味着这不应该是空的?

另外,如何获取与此注释相关的图像?我以为它会存储在注释字典的内容中,但这在上面的代码中也没有返回任何内容...

关于为什么我不能首先使用 pdfStamper 的原因:我的 pdf 文档的其中一页必须调整大小(缩小)以便在页面底部添加一些文本,所以我必须使用 pdfWriter为此。

问:iTextSharp 5.0 如何获取评论标注的画线?

你的单题很多post...

When the loop is parsing my comment the annotName variable returns my name, so I am sure to parse the annotation I am looking for but the annotSubtype is equal Nothing, how is that possible?

According to the pdf specification at section 12.5.2 table 1666 (https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf), the subtype parameter is required, so wouldn't it means this should not be at nothing?

根据 ISO 32000-1 第 12.5.2 节中的 table 164,子类型 条目确实是 必需的 ,但当您尝试检索 string 时,它也指定为 name

Dim annotSubtype As PdfString = annotDict.GetAsString(PdfName.SUBTYPE)

因为您的 PDF 中注释的 Subtype 条目正确地是 name, GetAsString return s Nothing.

因此,改为调用 GetAsName 并期望 PdfName return 类型。


Also, how can I get the image related to this annotation? I thought it would be stored in the content of the annotation dictionary but this is also returning nothing in the code above...

Contents 条目在与上面相同的 table 中指定为 可选 并且(如果存在)具有一个 文本字符串 值,其中包含应为注释显示的 文本,或者,如果此类注释不显示文本,则注释内容的替代描述 human-readable form. 由于注释只是一个涂鸦,注释应该具有什么作为 Contents 值?

由于您的注释实际上是 Ink 注释,因此您可以在必需的 InkList 和可选的 BS 注释条目,参见 ISO 32000-1 第 12.5.6.13 部分的 table 182。

InkList 的值是一个包含 n 个数组的数组,每个数组代表一条描边路径。每个数组应是默认用户 space 中的一系列交替的水平和垂直坐标,指定沿路径的点。绘制时,点之间用直线或曲线以implementation-dependent的方式连接。

BS(如果存在)的值是边框样式字典(参见Table 166)指定线宽和破折号图案用于绘制路径。

注意,但是:注释字典的 AP 条目(如果存在)优先于 InkListBS 个条目。在您的 PDF 中,注释有一个外观条目。所以实际显示的内容是N普通流,其中包含绘制您的涂鸦的矢量图形指令。


about why I can't use pdfStamper at the first place : one of the page of my pdf document must be resized (downscaled) in order to add some text at the bottom of the page, so I must use pdfWriter for that.

首先,这只意味着你必须对那个特殊的页面做一些特殊的事情,没有必要通过复制它们来破坏所有页面 PdfWriter.您可以在单独的文档中操作该单页,然后使用 PdfCopy 从原始 PDF 复制该页面之前的页面,然后从单独的 PDF 复制该页面,然后再次从原始 PDF 复制该页面之后的所有页面。

因此,您只需要修复那个特殊页面的注释,其他页面的注释可以保持不变。

此外,如果您准备好使用低级 iText 例程,您甚至可以使用 PdfStamper。特别是在标记之前,您可以将静态 PdfReader 方法 GetPageContent 应用于特殊页面的页面字典,以将页面内容检索为字节数组,从中构建一个新的字节数组,在其中添加仿射进行缩小的转换,并使用底层 PdfReader

SetPageContent 方法将新字节数组设置为相关页面的内容

即使在这种情况下,您也必须调整注释坐标(它们的矩形和其他坐标,例如 InkList 在您的情况下)...


Question: How can I get the drawn line of a comment annotation with iTextSharp 5.0?

见上,涂鸦的标注是Ink标注,绘制路径在InkListBS 其字典的条目并在其正常外观流中另外实例化。