首页 > 解决方案 > PDFClown MarkerContent 只给出前两个 ContentObjects

问题描述

我是 PDFClown 的新手,在解析我的 pdf 内容时需要帮助。

我的 PDF 有大量的 MarkedContents,当转换为 Stream 时会显示这些内容。

但我无法将它们解析为对象以提取其中包含的路径信息,这是我的目标。

这是我的代码 -

if(level.Contents[i] is MarkedContent)
{

 PdfDataObject ContentDataObj = level.Contents.BaseDataObject;
 PdfIndirectObject pdfIndirectObject = level.Contents.BaseDataObject.IndirectObject;

 PdfStream ContentStream = (PdfStream)ContentDataObj.Resolve();


 ContentParser contentParser = new ContentParser(ContentStream.GetBody(true).ToByteArray());
 IList<ContentObject> markerContentObjList = contentParser.ParseContentObjects();

 //Here i am getting only two Content Objects, where as the stream has so many distinct Marked Contents

 for (int k = 0; k < markerContentObjList.Count; k++)
 {

 }
}

下面是 DOM Inspector 截图和流数据

在此处输入图像描述

标签: pdfclown

解决方案


简而言之

PDF 的内容流中存在多个错误,尤其是关闭的对象多于打开的对象的错误。这很可能导致解析过早停止。即使不是,PDF Clown 也会以不同于预期的方式关联对象的开始和结束。因此,该问题的唯一真正解决方法是要求文档的来源提供完整的版本。

第一个内容流

您提供的屏幕截图显示了您的第一页内容流:

第一个内容流

该页面的第二个内容流表现出与此相同的问题:

标记内容序列的不匹配开始和结束

如果我们查看标记的内容运算符,我们会看到

/OC /Heading BDC
...
EMC
EMC
/OC /Heading BDC
...
EMC

如您所见,第一个BDC有两个 EMC运算符。这是无效的。赋予 ISO 32000-2 第 14.6 节标记的内容

无效的填充运算符

此外,在文本对象之后有一个 Fill 运算符:

BT
...
ET
f

这也是无效的,路径绘制运算符只允许在路径对象或剪切路径对象之后,而不是在文本对象之后。授予 ISO 32000-2 图 9图形对象

一个相关的 PDF 小丑问题

实际上,PDF Clown 中存在一个错误,它无论如何都无法使用 PDF Clown 处理标记的内容:PDF Clown 假定标记的内容部分和保存/恢复图形状态块彼此正确包含并且不重叠,请参阅此答案细节。该假设是错误的,并导致该答案中解释的图形状态内容不正确。

因此,应该按照那里的说明从 PDF Clown 中修补标记的内容支持,以至少具有正确的图形状态信息。此后,显然,除非您自己添加正确的支持,否则您将无法正确处理标记的内容。

为什么 PDF 小丑在第一流结束时停止

如您所见,PDF Clown 不是在额外的EMC之后停止,而是在第一个内容流结束时停止。

这是由于上面解释的 PDF Clown 问题:基于标记的内容部分和保存/恢复图形状态块正确包含在彼此中的假设,PDF Clown 只是让EMCQ关闭最近打开的并且仍然打开标记的内容部分或保存/恢复图形状态块而不检查它是否匹配。

因此,它匹配流中的打开和关闭运算符,如下所示:

[Start of page content]
.  q
.  .  /OC /Heading BDC
.  .  EMC
.  EMC
.  /OC /Drawing BDC
.  EMC
Q

因此,对于 PDF Clown,最后一个Q与内容中的初始q不匹配,而是与页面内容本身的开头匹配。

我认为 PDF Clown 在这里停止解析,因为它假设它已经找到了页面内容的结尾。


推荐阅读