pdfclown - 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 截图和流数据
解决方案
简而言之
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 只是让EMC和Q关闭最近打开的并且仍然打开标记的内容部分或保存/恢复图形状态块而不检查它是否匹配。
因此,它匹配流中的打开和关闭运算符,如下所示:
[Start of page content]
. q
. . /OC /Heading BDC
. . EMC
. EMC
. /OC /Drawing BDC
. EMC
Q
因此,对于 PDF Clown,最后一个Q与内容中的初始q不匹配,而是与页面内容本身的开头匹配。
我认为 PDF Clown 在这里停止解析,因为它假设它已经找到了页面内容的结尾。
推荐阅读
- javascript - 如何为 Intl.DateTimeFormat 设置全局选项
- python - 有没有办法将整个随机森林放入一个图中,而不是一对一的单个估计器?
- php - 查找单词是否存在于数组或字符串PHP中
- mongodb - mongos 从不同应用程序查询时返回空集合
- python - 如何在cygwin中运行的python中拦截ctrl + c命令
- android - 如何修复 Android/Webrtc/PeerConnection/createOffer 中的“m=video 9 UDP/TLS/RTP/SAVPF 0”问题
- git - Git 使用未知方法对我的 bitbucket 进行身份验证
- progressive-web-apps - PWA 添加到主屏幕无法按预期工作
- rest - 带有 x-www-form-urlencoded 消息类型服务调用的 WSO2 ESB
- android - 一个 Firebase 应用程序(一个 google_services.json)可以在两个不同包名的 Android 应用程序中使用吗