PDFBox 跳过文本
PDFBox skipping text
我正在使用 Apache pdfbox 阅读扫描的 pdf。某些 pdf 中的文本顺序有时会出现混乱。例如,在下图中,您可以注意到在从 Adobe Reader 中为 pdf 选择文本时如何完全跳过一个部分。当使用 pdfbox 以编程方式读取 pdf 时,也会发生同样的情况。我知道这与pdf结构有关。但是,我希望在 SO 中找到以下问题的答案:
- 为什么在 pdf 中会发生这种情况?
- 如何在 java 中以编程方式检测此问题?可能的方法是什么?
- 这个问题的解决方法是什么? (除了在 PDFStripper 中阅读设置 readSorted 为 true)
部分pdf文件here可供下载。
为什么在 pdf 中会发生这种情况?
您看到的 PDF 页面的内容是按照其内容流中的一系列指令绘制的最终静态图像。这些指令主要是设置一些 属性(颜色、字体、...)或实际绘制一些东西(“从 A 到 B 画一条线”、“从 B 开始绘制文本字符串 A”、...)。 PDF 标准不要求按阅读顺序排列这些说明,例如字符串“Hello world”可以通过先绘制“world”然后再绘制“Hello”来绘制。
默认情况下,PDFBox 文本剥离器会按照绘制的顺序提取文本。例如。假设在您的页面上有四个文本片段 A、B、C 和 D 明显按该顺序排列但按 A、C、D 和 B 的顺序绘制。默认情况下,PDFBox 将按后者的顺序提取它们,A、C 、D 和 B。(如果你要求它排序,你会得到从上到下、从左到右的顺序。)
Adobe Reader 也按照绘制的顺序标记文本。例如。再次假设在您的页面上有四个文本片段 A、B、C 和 D 明显按该顺序排列但按 A、C、D 和 B 的顺序绘制。如果您从 A 标记到 C,则不会标记 B , 只有 A 和 C.
例如您的 PDF
您的文档第 2 页的绘制顺序确实很奇怪:
页面内容流以绘制名为 X0 的表单 Xobject 的指令开始。您可以将此类对象视为类似 macros 的对象,独立的内容流可以包含在其他内容流的绘制中。因此,现在绘制了该表单 Xobject 的内容流:
Xobject X0 内容流以绘制图像 Xobject 的指令开始。 Image Xobjects 包含多种格式的位图图形。有问题的位图包含扫描页面 除了所有字母 ,即基本上是污点和几行:
此后有大量的文字绘制说明绘制所有段落除了第7段和第8.01段:
此后表单 Xobject 的内容流结束,因此在页面内容流中继续执行。
页面内容流继续绘制两个缺失段落的文本绘制指令:
这解释了您的观察结果:
标记文本的开头和结尾以 Xobject 的形式绘制。因此,仅标记 Xobject 形式的文本,而不标记稍后在页面内容流中绘制的两个段落。
顺便说一下,如果你想知道为什么文本看起来像位图扫描图像,尽管它被绘制为文本......这里使用的字体是从扫描页面中切割出包含OCR 机制将什么视为单个字形。这有时并不完全对应于单个字符,该字体中的某些字形对应于多个字符:
如您所见,对于某些字符,字体中有多个字形(例如小写 'o'),并且有一些字形包含多个字符(例如 'es' 或 'mi').
这个问题的解决方法是什么? (除了在 PDFStripper 中阅读设置 readSorted 为 true)
嗯,你必须决定你想要什么。您希望文本按绘制顺序排列或按排序顺序排列。
如果你想要按绘图顺序,每隔一段时间就会有文档在文本块的顺序中出现这种不稳定的跳跃。
如果您想要不同的顺序,则必须进行排序。 PDFBox 提供的排序是一种简单的从上到下、从左到右的排序。如果您有不同的排序方式,您可以从存储字形的文本剥离器中检索 TextPosition
对象以及它们在页面上的位置、大小和方向,然后自己对它们进行排序。
如何在 java 中以编程方式检测此问题?可能的方法是什么?
“这个”到底是什么意思?
你的意思是文字绘制说明不是从上到下,从左到右绘制的吗?
为此,您可以简单地覆盖 PDFTextStripper
方法 processTextPosition(TextPosition)
或 writeString(String, List<TextPosition>)
中的任何一个,并分析 TextPosition
实例中的位置。如果他们突然向上跳或者(在同一条线上)向左跳,你发现了这样的情况。
或者你的意思是文字绘制说明不按阅读顺序绘制?
这个很难,有多种情况阅读顺序确实又跳起来了,比如在多列文本或插入文本框的情况下。这绝对超出了堆栈溢出的答案。
我正在使用 Apache pdfbox 阅读扫描的 pdf。某些 pdf 中的文本顺序有时会出现混乱。例如,在下图中,您可以注意到在从 Adobe Reader 中为 pdf 选择文本时如何完全跳过一个部分。当使用 pdfbox 以编程方式读取 pdf 时,也会发生同样的情况。我知道这与pdf结构有关。但是,我希望在 SO 中找到以下问题的答案:
- 为什么在 pdf 中会发生这种情况?
- 如何在 java 中以编程方式检测此问题?可能的方法是什么?
- 这个问题的解决方法是什么? (除了在 PDFStripper 中阅读设置 readSorted 为 true)
部分pdf文件here可供下载。
为什么在 pdf 中会发生这种情况?
您看到的 PDF 页面的内容是按照其内容流中的一系列指令绘制的最终静态图像。这些指令主要是设置一些 属性(颜色、字体、...)或实际绘制一些东西(“从 A 到 B 画一条线”、“从 B 开始绘制文本字符串 A”、...)。 PDF 标准不要求按阅读顺序排列这些说明,例如字符串“Hello world”可以通过先绘制“world”然后再绘制“Hello”来绘制。
默认情况下,PDFBox 文本剥离器会按照绘制的顺序提取文本。例如。假设在您的页面上有四个文本片段 A、B、C 和 D 明显按该顺序排列但按 A、C、D 和 B 的顺序绘制。默认情况下,PDFBox 将按后者的顺序提取它们,A、C 、D 和 B。(如果你要求它排序,你会得到从上到下、从左到右的顺序。)
Adobe Reader 也按照绘制的顺序标记文本。例如。再次假设在您的页面上有四个文本片段 A、B、C 和 D 明显按该顺序排列但按 A、C、D 和 B 的顺序绘制。如果您从 A 标记到 C,则不会标记 B , 只有 A 和 C.
例如您的 PDF
您的文档第 2 页的绘制顺序确实很奇怪:
页面内容流以绘制名为 X0 的表单 Xobject 的指令开始。您可以将此类对象视为类似 macros 的对象,独立的内容流可以包含在其他内容流的绘制中。因此,现在绘制了该表单 Xobject 的内容流:
Xobject X0 内容流以绘制图像 Xobject 的指令开始。 Image Xobjects 包含多种格式的位图图形。有问题的位图包含扫描页面 除了所有字母 ,即基本上是污点和几行:
此后有大量的文字绘制说明绘制所有段落除了第7段和第8.01段:
此后表单 Xobject 的内容流结束,因此在页面内容流中继续执行。
页面内容流继续绘制两个缺失段落的文本绘制指令:
这解释了您的观察结果:
标记文本的开头和结尾以 Xobject 的形式绘制。因此,仅标记 Xobject 形式的文本,而不标记稍后在页面内容流中绘制的两个段落。
顺便说一下,如果你想知道为什么文本看起来像位图扫描图像,尽管它被绘制为文本......这里使用的字体是从扫描页面中切割出包含OCR 机制将什么视为单个字形。这有时并不完全对应于单个字符,该字体中的某些字形对应于多个字符:
如您所见,对于某些字符,字体中有多个字形(例如小写 'o'),并且有一些字形包含多个字符(例如 'es' 或 'mi').
这个问题的解决方法是什么? (除了在 PDFStripper 中阅读设置 readSorted 为 true)
嗯,你必须决定你想要什么。您希望文本按绘制顺序排列或按排序顺序排列。
如果你想要按绘图顺序,每隔一段时间就会有文档在文本块的顺序中出现这种不稳定的跳跃。
如果您想要不同的顺序,则必须进行排序。 PDFBox 提供的排序是一种简单的从上到下、从左到右的排序。如果您有不同的排序方式,您可以从存储字形的文本剥离器中检索 TextPosition
对象以及它们在页面上的位置、大小和方向,然后自己对它们进行排序。
如何在 java 中以编程方式检测此问题?可能的方法是什么?
“这个”到底是什么意思?
你的意思是文字绘制说明不是从上到下,从左到右绘制的吗?
为此,您可以简单地覆盖
PDFTextStripper
方法processTextPosition(TextPosition)
或writeString(String, List<TextPosition>)
中的任何一个,并分析TextPosition
实例中的位置。如果他们突然向上跳或者(在同一条线上)向左跳,你发现了这样的情况。或者你的意思是文字绘制说明不按阅读顺序绘制?
这个很难,有多种情况阅读顺序确实又跳起来了,比如在多列文本或插入文本框的情况下。这绝对超出了堆栈溢出的答案。