c# - 使用 iTextSharp 提取 PDF 注释不一致的原因)

标签 c# pdf hyperlink annotations itext

场景:

我有一个应用程序,它利用 iTextSharp 来搜索 PDF 文件中的超链接。

PDF 中的超链接是文件结构中“注释对象”的子类型,因此我的代码本质上是 (1) 读取文件,(2) 循环浏览页面,(3) 获取页面的注释集合,(4)提取页面的超链接注释。

问题

有时,表示给定页面的“pdf 字典”对象没有注释集合(无 /ANNOTS)键。因此,尝试获取此类集合将返回 null。这是一个问题,因为当相关页面上存在明显可见且可点击的链接时,这种情况时不时就会发生。

请注意,可点击在这里很重要,因为我知道纯文本中可能存在 URL 地址,但我不关心这些,只关心实际的真实超链接。 p>

代码

我发现类似的问题(http://stackoverflow.com/questions/6959076/reading-hyperlinks-from-pdf-file)提供的答案几乎正是我已经使用的代码。主要区别在于:

// My code
var pdfAnnotations = (PdfArray)PdfReader.GetPdfObject(pageDict.Get(PdfName.ANNOTS));
foreach (var annotation in pdfAnnotations.ArrayList) {}
                    {

// Chris' code                        
var annotsArray = pageDict.GetAsArray(PdfName.ANNOTS); 
foreach(var annotation in annotsArray.ArrayList) { }

// My pageDict.Get() and Chris's pageDict.GetAsArray() methods both 
// return null because there is no ANNOTS key present in pageDict.

问题

为什么是空值?一个带有明显可见/可点击链接的PDF文档怎么可能没有注释集合呢?文件结构中是否还有其他表示超链接/URI 的 PdfObject 子类型?

谢谢

最佳答案

那么让我尝试猜测一下。 (没有样本可供分析,就没有办法做任何其他事情。)

顺便说一句,在 PDF 代码中,它从不 /ANNOTS - PDF 键区分大小写! -- 始终是 /Annots

在 PDF 源代码中,像 /Annots 这样的 ASCII 字符串作为名称对象可以用以下任何替代方式表示。根据 PDF 规范,这些都是“合法的”(请参阅​​ PDF-1.7 specification 的第 7.3.5 段,名称对象):

 /Annots
 /#41nnots      # '#41' is the hex represenation of ASCII 'A' in PDF
 /A#6Enots      # '#6E' is the hex represenation of ASCII 'n' in PDF
 /An#6Eots      # '#6E' is the hex represenation of ASCII 'n' in PDF
 /A#6E#6Eots    # '#6E' is the hex represenation of ASCII 'n' in PDF
 ...
 /Annot#73      # '#73' is the hex represenation of ASCII 's' in PDF

你明白了...(如果我的快速计算是正确的,你可以做出 32 种不同的变体...)

顺便说一句,这是黑帽黑客用来混淆恶意软件 PDF 中 /#4Aava#53cript key 的最简单方法之一!更完整的潜在方法列表请参见 'Corkami Project' .)

也许您的 iTextSharp 版本(您没有声明)无法正确处理对 /Annots 名称键的所有表示形式的搜索?

如果是这样,那么我建议您在查找 /Annots 之前标准化每个 PDF 的副本。您可以借助命令行工具(及其 API)qpdf 成功实现此目的。 :

 qpdf --qdf helloworld.pdf qdf---helloworld.pdf

让我们看看:

 kp@mbp:~$  grep nnots helloworld.pdf
      /#41nnots 57 0 R

 kp@mbp:~$  qpdf --qdf helloworld.pdf qdf---helloworld.pdf

 kp@mbp:~$  grep nnots qdf---helloworld.pdf
 qdf---helloworld.pdf:     /Annots 57 0 R

关于c# - 使用 iTextSharp 提取 PDF 注释不一致的原因),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11400151/

相关文章:

java - 如何跳转到本地pdf中的页面?

javascript - 为链接提供 onclick 函数

ms-access - 如何隐藏嵌入式 PDF 查看器控件中的导航 Pane ?

c# - 命名索引器属性可能吗?

c# - 等待 this.ShowMessageAsync 在 WPF C# 中不起作用

C# 在 Windows 启动时运行应用程序最小化

linux - 如何搜索多个pdf文件的内容并返回pdf的文件名?

css - 摆脱博主图片链接

hyperlink - 在 Gmail 中撰写邮件的 URL(具有完整的 Gmail 界面并指定收件人、密件抄送、主题等)

c# - 如何创建一个名为 "checked"的属性?