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

2023-12-27

我需要将一些 PDF 转换回文本。我尝试了很多软件和在线工具,但结果总是平庸。

从技术上来说为什么这么难?


我们不要假设您正在谈论的 PDF 仅包含一些位图图像,因为很明显,在这种情况下您只能诉诸 OCR 及其所有限制。

我们假设文本是在手边的 PDF 中绘制的。

PDF 页面上绘制的内容由sequence of 指示在该页面的内容流中。 “在页面上绘制文本”意味着在这些指令中,有一些设置后续指令要使用的字体,一些设置后续指令要使用的文本位置和方向,还有一些实际绘制由“给出的文本”字符串参数”。

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

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

  • 每种字体可以有自己的编码;要提取文本,除了绘制文本并连接其字符串内容的指令之外,不能简单地忽略所有内容,您始终必须考虑当前字体(一些非常简单的文本提取器会忽略这一点,因此经常无法返回合理的内容) ;

  • 有大量预定义的编码,其中一些让您想起您所知道的编码,例如WinAnsi编码,很多你可能不知道,例如添加-RKSJ-H;这些编码可以使用每个字形的恒定字节数,也可以是混合多字节;因此文本提取器必须首先支持很多编码;

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

下一个问题是理解字符串的顺序:

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

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

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

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

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

  • 通常对于粗体文本,人们使用不同的粗体字体程序;如果手头没有,人们有时会发挥创意,通过以微小的偏移量打印相同的文本两次来模仿粗体;使用稍大的偏移(或不同的变换)和不同的颜色,可以模拟阴影效果;如果文本提取器不尝试识别这一点,您最终会在输出中出现一些重复的字符。

由于额外信息不完整或错误,会出现更多问题:

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

  • 甚至有些 PDF 的信息相互矛盾,例如有一个错误转Unicode地图,但正确的信息实际文本入口;一些 PDF 创建者使用它来允许从某些程序进行正确的复制和粘贴(首选实际文本在这种情况下进入),同时在其他程序的输出中注入错误(首选转Unicode则信息)。

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

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

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

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

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

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

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

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

...

同时您肯定已经了解为什么文本提取结果可能不是最佳的。请放心,上面的列表并不完整,文本提取仍然存在更多复杂性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么将 PDF 转换为纯文本如此困难? 的相关文章

  • 未找到 EOF 标记 - 如何在 PyPDF 和 PyPDF2 中修复?

    我正在尝试使用 Python 将几个 PDF 文件合并为一个 PDF 文件 我已经尝试过 PyPDF 和 PyPDF2 在某些文件上 它们都抛出相同的错误 PdfReadError 未找到 EOF 标记 这是我的代码 page files
  • 如何使用 MigraDoc 让表情符号出现在生成的 PDF 中

    我正在尝试生成包含一些表情符号的 PDF 但没有成功 为了使其简单且可重现 这里是代码 Document document new Document Section section document AddSection Paragraph
  • 将 Highcharts 导出为 PDF(使用 javascript 和本地服务器 - 无互联网连接)

    我在我的应用程序中使用 Highcharts 没有任何互联网连接 我的 html 页面上有多个图表 我想生成一个包含该页面中所有图表的 PDF 报告 我怎样才能做到这一点而不将数据发送到互联网上的任何服务器 我将感谢您提供的任何帮助或任何示
  • 使用 Poppler Qt4 C++

    我需要在我的应用程序中使用 pdf 查看器库 我使用 C 和 QT 我下载了Poppler http poppler freedesktop org 和代码示例Poppler Qt4 界面库 http people freedesktop
  • LibreOffice - 多页 pdf 转换为单页 docx 文件

    我正在尝试使用命令行将 PDF 文件转换为 docx soffice infilter writer pdf import convert to docx MS Word 2007 XML pdf 输入 PDF 包含多个页面 打开输出 Do
  • 如何在 ionic 应用程序中显示 pdf 文件而无需下载

    我所做的事情 在应用程序浏览器中使用 使用谷歌文档 使用的网页视图 所以我尝试了所有这些方法来使用 ionic 在 Android 设备中显示 pdf 文件 但没有用 我可以在所有这些方法中看到下载按钮 谁能告诉我如何在没有用户下载选项的情
  • 如何将 RTF 文件转换为 pdf 文件?

    如何将 RTF 文件转换为 PDF 文件 我有 adobe PDF 打印机 我应该使用它吗 如果是这样 我如何以编程方式访问它 您可以使用 PDF 打印机 但仍有一些问题需要解决 为了处理跨多个页面的文本 您需要本文 http msdn m
  • 在 ionic 中从 Base64 打开 pdf

    因此 我将 Jasper 报告转换为 pdf 然后在 REST 控制器中转换为 base64 我该如何将其传输到我的 ionic 3 应用程序 我研究了 Ionic Native Document Viewer 但为了做到这一点 我需要将文
  • Linux:命令行实用程序将 RTF 转换为 PDF?

    有什么建议可以将 RTF 转换为 PDF 吗 我需要从 LAMP 应用程序执行此操作 因此像 GhostScript 这样的命令行实用程序将是理想的选择 或者 您可以使用 libreoffice 来完成此任务 libreoffice hea
  • 使用 iTextSharp 5.3.3 和 USB 令牌签署 PDF

    我是 iTextSharp 和 StackOverFlow 的新手 我正在尝试使用外部 USB 令牌在 C 中签署 PDF 我尝试使用从互联网上挖掘的以下代码 Org BouncyCastle X509 X509CertificatePar
  • 创建仅在使用 PDFBox 打印时显示的水印(pdf 可选内容)

    我遇到过许多使用 PDFBox Layer Utility 的appendFormAsLayer 方法的示例 如下所示 Places the given form over the existing content of the indic
  • 使用 Tabula 通过 Python 读取 pdf 时出现 Java 错误

    我已经安装了 tabula 库 用于使用 python 将 pdf 读取到 pandas 数据框中 但是当我运行代码时 import tabula df tabula read pdf sample1 pdf pages 1 我得到了例外
  • 使用 ImageMagick 和/或 GhostScript 将多页 PDF 转换为多个 JPG

    我正在尝试将多页 PDF 文件转换为一堆 JPEG PDF 中的每一页一个 我花了几个小时寻找如何做到这一点 最终我发现我需要安装 Ghostscript 所以我就这么做了 来自这个网站 http downloads ghostscript
  • 使用 PHP 将值插入可编辑 PDF,并保持可编辑状态

    我有一个带有可编辑字段的 PDF 我希望将 HTML 表单中的值传递到此 PDF 中 我尝试过使用 FPDF 并且它有效 但是将值传递到 PDF 后 pdf 中的字段不再可编辑 另一个缺点是 在将值传递到 PDF 时 我们必须为每个字段指定
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • Windows 如何批量打印 PDF 文档?

    在我的机器上 当在 Windows 资源管理器中选择多个 PDF 文档时 右键单击并选择Print Adobe Acrobat Reader 将最小化打开 所有文档都会静默发送到打印机 我想做Windows一样的事情 但是怎么做呢 我在用P
  • 在 RMarkdown 输出到 PDF 时缩进而不添加项目符号点或编号

    之前有人问过如何在没有项目符号的情况下缩进文本 RMarkdown 中的点 但这是针对 HTML 输出的 在 RMarkdown 中缩进而不添加项目符号点或数字 https stackoverflow com questions 47087
  • 在 Flutter 中显示 iOS 的 PDF 内联文件

    我正在 flutter 中专门为 iOS 开发一个应用程序 现阶段 我需要向其中添加 PDF 文件 问题是 flutter 没有原生的方式来显示 PDF 文件 据我研究 由此tread https github com flutter fl
  • 如何从 pdf C# 中获取具有特定颜色的文本

    我必须将 pdf 文件中的数据放入特定的数据库结构中 这要求我能够从 pdf 文件中获取某些数据 由于 pdf 没有任何标签等 我想知道是否可以根据颜色获取文本 比如说我想要所有的红色文本 或者我想要文档中的所有斜体文本 这在 C 中可能吗
  • 在 Flash Player 10 中打开 pdf

    我需要在 Flash Player 10 中打开 PDF 该 swf 不会在浏览器中运行 并且系统上不会有 adobe reader 程序 我需要知道是否可以在 Flash 播放器中打开 PDF 而无需以任何方式进行转换 我在谷歌上搜索了无

随机推荐

  • 在C中,是否保证数组起始地址小于其他元素的地址?

    换句话说 当做 index array x array 0 是否总是保证 根据 C 标准 array 0 地址顺序是有保证的 关系运算符的行为定义在C11 6 5 8p5 http port70 net nsz c c11 n1570 ht
  • 分页逻辑怎么写?

    任何人都可以提供一些想法 逻辑来为我正在处理的搜索页面编写分页逻辑吗 我掌握的信息是总页数对于该搜索 每页10条记录我还收到了上一页和下一页的页码 编写逻辑没问题 我需要做的就是提取该信息并填充 我还获取我所在页面的信息 我只能显示 10
  • 导入com.google.android.gms.gcm.GoogleCloudMessaging无法解析[重复]

    这个问题在这里已经有答案了 我正在尝试在 Android 应用程序中使用通知 我发现了很多 tuto 但都使用了已弃用的 com google android gcm pakage 我发现我必须使用 com google android g
  • Apache - 处理 TCP 连接,但不处理 HTTP 请求

    我有一个 GPS 单元 可以通过 TCP 连接发送数据 但我无法修改它发送的消息 因此它会以 HTTP 请求的形式到达我的服务器 它只能发送消息以预定义的格式 所以 我有以下问题 1 是否可以让 Apache 处理不以 HTTP 请求形式出
  • “Hello World”——TDD 方式?

    自从我接触 TDD 以来 我一直在思考这个问题 构建 Hello World 应用程序的最佳方法是什么 这将在控制台上打印 Hello World 使用测试驱动开发 我的测试会是什么样子 以及大约什么班 Request No 类似维基百科
  • Apache Flink(如何唯一标记作业)

    是否可以使用唯一的名称来标记作业 以便我可以在以后停止它们 我真的不想 grep 并保留作业 ID 简而言之 我想在部署过程中停止一项作业并部署新作业 您可以在启动作业时为其命名execute name String 打电话 例如 val
  • 如何清除 IE 的图标缓存?

    我为我的网站定义了一个最喜欢的图标 任何访问过该网站的浏览器after我添加的图标可以很好地显示favicon 但我自己的浏览器拒绝显示图标 我已经尝试了我能想到的链接的所有变体
  • Java大文件AES加密很慢

    我正在尝试使用 AES CBC 算法加密 512 Mb 文件 大约需要 7 秒 这太长了 如何减少加密时间并使其更快 我使用固定密钥并尝试使用 CipherOutStream 以及 cipher update 而不是 cipher dofi
  • 为什么 Haskell 中基于 [Char] 的输入比基于 [Char] 的输出慢得多?

    这是一个不使用的常识 Char 在 Haskell 中读取大量数据 一用ByteString来完成这项工作 对此通常的解释是Chars 很大并且列表增加了它们的开销 然而 这似乎不会对输出造成任何问题 例如下面的程序 main intera
  • git重置后未暂存的文件消失了--hard

    我尝试过git reset hard HEAD n from git reflog我丢失了当前未暂存文件的所有内容 未暂存的文件是最后一个git add我做到了 在那之前我尝试过git reset到最后git commit 我所有的文件都消
  • 反应 onClick 问题

    我是 React 新手 我正在尝试将 onClick 事件连接到图像 以查看已按下的对象但无法使其工作 我已经尝试了在该网站上找到的几个答案 但没有一个起作用 可能是因为 var createItem jsx React DOM var R
  • Mono for Android OnPause 事件在 Galaxy Nexus 上未触发

    我整理了我的第一个 Mono for Android 项目 目标 API 级别 8 最低 Android 2 2 并将其部署到运行 2 3 4 的 HTC Incredible 1 一切都很顺利 并且在我的主要活动中出现了断点OnCreat
  • 对话框 ui 中的复选框不可选中

    我正在尝试使用 jQuery UI 对话框解决 z index 问题 类似于问题无法选择或取消选择 jQuery UI 模态对话框中的复选框 https stackoverflow com questions 10542327 cant s
  • 如何在 docker 容器中运行 npm 命令?

    我正在尝试在 docker 容器内以开发模式运行角度应用程序 但是当我使用 docker compose build 运行它时 它可以正常工作 但是当我尝试放置容器时 我收到以下错误 ERROR for sypgod Cannot star
  • jackson - 具有受控精度的双精度的 json 编码

    我正在使用双值数组对复杂的 Map 结构进行编码 高精度并不重要 输出大小才是重要的 所以我试图让 JSON 工具 在本例中为 Jackson 使用提供的 DecimalFormat 序列化双精度值 以下是我的最佳镜头 但由于对象映射器未选
  • C++(Windows)中的分配数及其可预测性

    我在用 CrtDump内存泄漏 http msdn microsoft com en gb library d41t22sb aspx识别我们软件中的内存泄漏 我们在多线程应用程序中使用第三方库 这个库确实存在内存泄漏 因此在我们的测试中
  • 加载 Google 地图时出现问题 - SensorNotRequired

    我正在尝试在 WordPress 网站上运行 Google 地图 代码在此完美运行JSFIDDLE http jsfiddle net 3VKQ8 55 但是当我将其带到 WordPress 时 我收到此错误 Google 地图 API 警
  • 线程过剩: glutPostRedisplay 被忽略

    我有一个程序可以更新程序输出 然后程序的状态会发生变化 当时间计时器 不是 openGL 计时器 而是在线程中实现的 发生时 以及从 glut 注册键盘输入 使用 glutKeyboardFunc 回调 时 就会发生这种情况 这两个事件都会
  • 缓冲区和缓存的区别?

    任何人都可以详细说明 系统内存中的缓冲区和缓存有什么区别 A buffer只是一个在短时间内保存数据的容器 当在任何给定时间出现的数据多于消费者可以使用 处理的数据时 这是一种先进先出的情况 数据传入 可能会被缓冲 并在一段时间后按照传入的
  • 为什么将 PDF 转换为纯文本如此困难?

    我需要将一些 PDF 转换回文本 我尝试了很多软件和在线工具 但结果总是平庸 从技术上来说为什么这么难 我们不要假设您正在谈论的 PDF 仅包含一些位图图像 因为很明显 在这种情况下您只能诉诸 OCR 及其所有限制 我们假设文本是在手边的