【问题标题】:PDFBox skipping textPDFBox 跳过文本
【发布时间】:2020-11-09 12:05:44
【问题描述】:

我正在使用 Apache pdfbox 读取已扫描的 pdf。在某些 pdf 中,文本的顺序有时会显得混乱。例如,在下图中,您可以注意到从 Adob​​e Reader 为 pdf 选择文本时如何完全跳过一个部分。当使用 pdfbox 以编程方式读取 pdf 时,也会发生同样的情况。我知道这与pdf结构有关。但是,我希望在 SO 中找到以下问题的答案:

  1. 为什么会在 pdf 中发生这种情况?
  2. 如何在 java 中以编程方式检测这个?有哪些潜在的方法?
  3. 此问题的解决方法是什么? (除了在 PDFStripper 中读取设置 readSorted 为 true)

部分pdf文件是here供下载。

【问题讨论】:

  • 请分享 PDF。
  • @mkl 更新了 pdf 链接

标签: java pdfbox


【解决方案1】:

为什么会在 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 的指令开始。您可以将此类对象视为类似 的东西,独立的内容流可以包含在其他内容流的绘制中。因此,现在绘制了该表单 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 实例中的位置。如果他们突然向上跳或(在同一条线上)向左跳,你就会发现这种情况。

  • 或者你的意思是文字绘制说明没有按阅读顺序绘制?

    这很困难,有多种情况下阅读顺序会再次跳升,例如在多列文本或插入文本框的情况下。这绝对超出了堆栈溢出的答案。

【讨论】:

  • 我想我能够使用你提到的第一种方法来实现我想要的。谢谢您的回答。我会在 18 小时内奖励赏金 - 看起来必须等到那时。
  • 不用着急。在你提供赏金之前,我已经开始回答了,这不仅仅是为了赏金。 ;)
  • 即使没有悬赏,你的答案也值得悬赏 :-D - 太好了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-13
  • 2017-02-22
  • 2014-05-29
  • 1970-01-01
  • 2018-09-10
相关资源
最近更新 更多