2016-11-15 52 views
0

我正在尝试使用iTextSharp读取PDF注释的外观流,并从流中获取内容文本。当资源不在字典中时如何从外观流中提取内容?

我用下面的代码:

public String ExtractAnnotationText(PdfStream xObject) 
     { 
      PdfDictionary resources = xObject.GetAsDict(PdfName.RESOURCES); 
      ITextExtractionStrategy strategy = new LocationTextExtractionStrategy(); 
      PdfContentStreamProcessor processor = new PdfContentStreamProcessor(strategy); 
      byte[] contentByteArray = ContentByteUtils.GetContentBytesFromContentObject(xObject); 
      processor.ProcessContent(contentByteArray, resources); 
      return strategy.GetResultantText(); 
     } 

xObject从外观字典检索和传递这样的:

PRStream value = (PRStream)appearancesDictionary.GetAsStream(key); 
String text = ExtractAnnotationText(value); 

这通常非常适用于正从注释外观文,但我找到了一个FreeTextCallout的示例,其中xObject没有/Resources密钥,如其hashMap所示:

[/Type, /XObject] 
[/Subtype, /Form] 
[/FormType, 1] 
[/Length, 71] 
[/Matrix, [1, 0, 0, 1, -28.7103, -643.893]] 
[/BBox, [28.7103, 643.893, 597.85, 751.068]] 
[/Filter, /FlateDecode] 

在这种情况下,是否有另一种方法来构造一个Resources字典传递到PdfContentStreamProcessor.ProcessContent()?或者甚至以不同的方式获取文本而不使用ProcessContent()

回答

2

在此PDF规范声明:

资源字典应与内容流中的下列方式之一进行关联:

  • 这才是价值的内容流一个页面的内容条目(或者是一个数组的元素,它是该条目的值),资源字典应由页面字典的资源指定或继承,如desc在页面对象的某个祖先节点的7.7.3.4,“页面属性的继承”中被分解。

  • 对于其他内容流,一致性编写者应在流的字典中包括一个资源条目,指定包含该内容流使用的所有资源的资源字典。这将适用于定义表单XObjects,模式,Type 3字体和注释的内容流。

  • 写入服从早期版本PDF的PDF文件可能省略了页面上使用的所有格式XObjects和Type 3字体的资源条目。从这些表单和字体引用的所有资源都应从其使用页面的资源字典继承。这个构造已经过时,不应该被合格的作者使用。

(部分7.8.3 - 资源字典 - ISO 32000-1的)

因此,你发现任一例子是,第三个选项的情况下,或例如仅需要根本没有资源,或者你的示例文件被破坏。

+0

可能是一个破碎的文件;我的项目的目标是采用由Foxit错误构建的PDF,并修改它们以在Adobe Reader中呈现时正确运行。在这种情况下,也许我必须编写一个替代外观文本解析器。 – sigil

+0

*“Foxit错误地构建”* - Foxit以何种方式错误地构造pdfs? (我还没有认真对待它......) – mkl

+0

如果确认Foxit不正确地构造pdf文件,那么向他们发送错误报告可能会有用。 –