为什么将PDF转换为纯文本如此困难?

Dem*_*jon 1 pdf text-extraction

我需要将一些PDF转换回文本。我尝试了许多软性和在线工具,结果总是中等。

从技术上讲为什么如此困难?

mkl*_*mkl 8

我们不要假设您是在谈论仅包装一些位图图像的PDF,因为应该清楚的是,在这种情况下,您只能借助所有限制来诉诸OCR。

相反,我们假设在手边的PDF中绘制了文本。

什么是绘制一个PDF页面上是由确定序列说明该页面的内容流。页面上的“绘制文字”表示,在这些指令中,有一些设置了要使用的指令所使用的字体,一些设置了要使用的指令所使用的文本位置和方向,还有一些实际上是由“字符串参数”。

文本提取的任务是从内容流中获取指令序列,而不是按照字体和位置设置指令所示绘制文本,而是使用标准编码(通常是字符类型的编码)以合理的顺序导出文本所使用的编程语言/平台。

第一个问题是了解那些文本绘制指令的字符串参数的编码:

  • 每个字体可以有自己的编码;要提取文本不能简单地忽略所有内容,而是绘制文本并连接其字符串内容的指令,则必须始终考虑当前字体(某些极其简单的文本提取器会忽略此字体,因此,经常无法返回有意义的内容) ;

  • 有大量的预定义编码,有些提醒您知道编码,例如WinAnsiEncoding,许多您可能不知道,例如Add-RKSJ-H;这些编码每个字形可以使用恒定数量的字节,也可以是混合多字节;因此,文本提取器必须支持很多编码。

  • 编码也可能是完全临时的和任意的;特别是在嵌入子集字体的情况下,经常会看到需要通过从某个起始值处理字符代码而生成的即席编码;即给定字体在页面上使用的第一个字形被赋予起始值作为代码,下一个不同的字形被赋予起始值加一个,下一个不同的字形被赋予起始值加两个,依此类推;“ Hello World”和起始值48(ASCII值“ 0”)将得出“ 01223453627”;这些字体可能包含到Unicode的映射,但不是必需的。

下一个问题是弄乱字符串的顺序:

  • 字符串绘制指令可以以任意顺序出现,例如“ Hello”可以先绘制成“ lo”,然后移回“ el”,然后再移回“ H”;要提取文本,您不能忽略文本定位指令,而只能将文本字符串连接起来,则必须始终考虑当前位置(某些简单的文本提取器会忽略此位置,因此可能无法返回有意义的内容);

  • 多列文本可能会带来困难,可能会逐行绘制文本,例如,首先是第一列顶行的文本,然后是第二列顶行的文本,然后是第一列第二行,然后是第二列的第二行,依此类推;PDF中不需要任何暗示该文本是多列的。

另一个问题是识别格式或样式工件:

  • 单词之间的空格不必通过绘制空格标志来创建,也可以通过文本位置更改指令来完成;文本提取器不尝试识别由文本定位指令创建的间隙可能会返回没有空格的结果;另一方面,可以使用相同的技术以最佳距离绘制相邻字形,即字距紧缩;试图识别由文本定位指令创建的间隙的文本提取器可能错误地返回不应有空格的空格;

  • 有时将选定的单词“隔开”打印,以特别强调;在提取的文本中,这些间隙可能以空格字符表示,文本的自动后处理可能会视为单词分隔符;

  • 通常对于粗体文本,使用不同的粗体字体程序;如果还不行,人们有时会创造性地表现出来,并以相同的间隔两次印刷相同的文本来模仿粗体。通过稍大的偏移量(或不同的变换)和不同的颜色,可以模拟阴影效果;如果文本提取器无法识别出该错误,则最终在输出中会有一些重复的字符。

由于不完整或错误的额外信息会引起更多问题:

  • 字体的ToUnicode映射(从字符代码到Unicode的可选映射)可能不完整或包含错误;例如,这里有很多关于堆栈溢出的问题,这些问题涉及印度文字的不正确的ToUnicode映射;文本提取结果反映了这些错误;

  • 甚至有PDF的信息相互矛盾,例如ToUnicode映射中有错误,而ActualText条目中有正确的信息;一些PDF创建者使用它来允许从某些程序进行正确的复制和粘贴(在这种情况下,最好使用ActualText条目),同时在其他程序的输出中注入错误(然后,首选ToUnicode信息)。

如果您希望文本提取器仅提取页面中最终可见的文本,则会出现另一个问题:

  • 可能在当前剪贴区域之外或可见页面区域之外绘制文本;文本提取器需要牢记这些;

  • 可以使用“不可见”渲染模式绘制文本;文本提取器必须关注渲染模式;

  • 可以使用与背景相同的颜色来绘制文本;为了认识到这一点,文本提取器不仅可以查看当前指令和一些图形状态详细信息,还必须考虑到在文本位置预先绘制的任何内容;

  • 可以将文本绘制为剪切路径;为了识别该文本最后是否可见,只要剪切路径处于活动状态,文本提取器就必须跟踪在文本区域中绘制的内容;

  • 文本稍后可能会被其他内容覆盖;在这种情况下,文本提取器必须删除已识别的文本;但是根据混合模式和透明度设置的不同,这些覆盖物可能会或可能不会使文字发光;因此,为了获得正确的结果,文本提取器必须针对每个字形跟踪其绘制的颜色,背景色以及以后所有这些漂亮效果对这些颜色的影响;当然,字形颜色和背景色都可能很有趣,例如某些阴影颜色;并且所涉及的色彩空间可能不同,因此需要在色彩空间之间来回转换;等等。

此外,可能会在文本提取器通常不显示的地方绘制文本:

  • 一些工具通过将文本置于模式中并用该模式填充页面区域来隐藏文本提取中的文本;
  • 类似地,还有3型字体;类型3字体中的每个字符都由其自己的内容流表示;因此,工具可以在单个类型3字体字形的内容流中绘制所有文本,然后在页面上绘制该字形。

...

同时,您当然已经知道了为什么文本提取结果可能不够理想。可以肯定的是,以上列表并不完整,文本提取还有更多的复杂性。

  • @Demeter 我非常熟悉文本提取的问题,是的,但我只是实现了专门的文本提取器。通常一个人只需要处理一些并发症。OCR 有其自身的一系列并发症。什么是合适的方法,取决于具体情况。 (2认同)