【问题标题】:Get annotation from a pdf to add to another document从 pdf 中获取注释以添加到另一个文档
【发布时间】:2020-11-13 08:06:01
【问题描述】:

我使用的是 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 变量会返回我的名字,所以我肯定会解析我正在寻找的注释,但 annotSubtype 等于 Nothing,这怎么可能?根据第 12.5.2 节表 1666 (https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf) 的 pdf 规范,subtype 参数是必需的,所以这不是说这不应该是一无是处吗?

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

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

问题:如何使用 iTextSharp 5.0 获得注释注释的绘制线?

【问题讨论】:

标签: vb.net pdf itext pdf-generation


【解决方案1】:

您的帖子中有很多单一的问题...

当循环解析我的评论时,annotName 变量返回我的名字,所以我肯定会解析我正在寻找的注释,但 annotSubtype 等于 Nothing,这怎么可能?

根据第 12.5.2 节表 1666 (https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf) 中的 pdf 规范,子类型参数是必需的,所以这不是说这不应该是空吗?

根据 ISO 32000-1 第 12.5.2 节中的表 164,Subtype 条目确实是必需,但它也指定为 名称 当您尝试检索 字符串 时:

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

由于您的 PDF 中该注释的 Subtype 条目正确地是一个名称GetAsString 返回Nothing

因此,请改为调用 GetAsName 并期待 PdfName 返回类型。


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

Contents 条目在与上面相同的表中被指定为 可选 并且(如果存在)具有包含的 文本字符串应该为注释显示的文本,或者,如果这种类型的注释不显示文本,则以人类可读的形式对注释内容的替代描述。由于注释只是一个涂鸦,什么注释是否应该具有 Contents 值?

由于您的注释实际上是一个 Ink 注释,您可以在必需的 InkList 和可选的 BS 条目中找到涂鸦的表示注释见 ISO 32000-1 第 12.5.6.13 节的表 182。

InkList 的值是n 个数组组成的数组,每个数组代表一个描边路径。每个数组应是默认用户空间中一系列交替的水平和垂直坐标,指定路径上的点。绘制时,点应通过直线或曲线以实现相关的方式连接。

BS(如果存在)的值是一个边框样式字典(参见表 166),指定在绘制路径时应使用的线宽和虚线图案。 em>

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


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

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

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

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

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


问题:如何使用 iTextSharp 5.0 获得注释注释的绘制线?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 2021-08-04
    • 2020-12-30
    相关资源
    最近更新 更多