此 PDF 由 Abbyy Finereader 10 制作:
http://ebooks.zeitr.org/from_abbyy.pdf
您可以复制并粘贴第一句话并获得这个(非常好的)文本结果:
1955 年 11 月 20 日,“德国体操学校联盟”成立,成为德国私人体操教育协会的会员和指导老师的合集。
在使用 Ghostscript 9.02(64 位 Windows)进行一些处理后,我得到了这个文件:
http://ebooks.zeitr.org/after_ghostscript.pdf
现在第一句话看起来很奇怪——每个单词的最后一个字符前都有一个多余的空格。
“德国联邦体操学校” 的学生团体已经 20 强。 1955 年 11 月,他被编入了德国私立体操学校的教练协会。
这的主要负面影响是您无法在 Acrobat Reader 中搜索整个单词。我可以使用以下针对 Ghostscript 的最小参数集重现该效果:
-sDEVICE=pdfwrite ^
-dBATCH ^
-dNOPAUSE ^
-sstdout="myStdOut" ^
-sOutputFile="myDestFile.pdf" ^
mySourceFile.pdf
有任何想法吗?
答案1
我发现这是一个有趣的问题,并仔细研究了一下......
首先,我使用qpdf
命令行工具解压缩 PDF 数据流,以便更好地查看两个文件的源代码:
qpdf.exe ^
--qdf ^
from_abbyy.pdf ^
qdf--from_abbyy.pdf
qpdf.exe ^
--qdf ^
after_ghostscript.pdf ^
qdf--after_ghostscript.pdf
查看第一次插入额外空格的情况(它是原始字符串德国体操学校联合会转变为德国体操协会),我找到了以下PDF片段:
在 qdf--from_abbyy.pdf 中:
( Deutsche) Tj
0 Tc
(r) Tj
1 0 0 1 143.236 265.140 Tm %% Tm = 'text matrix' operator
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite) Tj
在 qdf--after_ghostscript.pdf 中:
( Deutsche)Tj
0 Tc
36.235 0 Td %% extra Td = 'move text current point' operator
(r)Tj
2.16501 0 Td %% Td = 'move text current point' instead of Tm
3.569 Tw
0.706 Tc
( Gymnastik-Schulleite)Tj
为了让您对这里使用的 PDF 图形运算符的含义有一点了解,下面是一个简短的列表:
Tj - show text
Tc - set character spacing
Tm - set text matrix
Tw - set word spacing
Td - move text current point
如您所见,Ghostscript 替换了原来的Tm
(文本矩阵Td
)运算符移动文本当前点) 一个,它还添加了一个额外的2.16501 0 Td
...我不知道这是为什么。我会向 Ghostscript 的 bugzilla 提交错误报告[*]看看他们是否有兴趣解决这个问题。
但请注意,如果我使用 Linux Acrobat Reader 9.4.2 并使用菜单操作,则不会发生此问题“文件 -> 另存为文本...”。在这种情况下,没有额外的空格(但有一些额外的换行符)。在 Linux 上,文本也无法正确搜索,并且在执行以下操作时也会显示额外的空格复制粘贴....
[*]当我完成后,我将在这里更新错误编号。
更新:
在对替换的操作员进行进一步思考之后Tm
,我现在认为这不应该是问题的根源。
意识到这一点后,我尝试使用 Ghostscript v8.71 而不是 v9.02 进行转换。我该说什么呢?v8.71 输出不会出现复制粘贴问题!
这意味着:Ghostscript 9.02 中存在一个问题,而 8.71 中不存在这个问题。最有可能的是,它与输出 PDF 中嵌入的字体指标有关。因为上面引用的 PDF 片段在 v8.71 输出中与在 v9.02 输出中相同……
更新 2:
Ghostscript 的 bugzilla 中错误条目的 URL:
更新 3:
目前看来,这个错误确实已经修复。我再次测试了 Ghostscript 版本,发现没有出现此问题:当前 Git (v9.10GIT) 和 Ghostscript v9.06。
答案2
如果您将包含文本的页面扫描为 PDF 并在其上运行 OCR 应用程序,则文本将添加到页面中,但“文本渲染模式”设置为不可见。它在那里,但不会呈现在屏幕上(或打印时呈现在纸上)。您看到或打印的是原始扫描图像。
我们如何才能使不可见的文字变得可见?
好吧,我们可以编辑 PDF...将文本渲染设置为不可见的 PDF 代码是这样的:
3 Tr
您目前无法在原文中找到此字符串来自_abbyy.pdf也不在来自_ghostscript.pdf因为 PDF 的部分内容是压缩的。所以我们尽可能借助以下工具来解压它们qpdf
:
qpdf \
--qdf \
from_abbyy.pdf \
qdf--from_abbyy.pdf
qpdf \
--qdf \
after_ghostscript.pdf \
qdf--after_ghostscript.pdf
现在我们可以轻松找到上述字符串(并且每个文件中只出现一次)。
让我们将其切换到可见的文本渲染模式之一。总的来说,我们可以在以下 8 种文本渲染模式中进行选择:
0 - fill glyph shapes
1 - stroke glyph shapes
2 - fill, then stroke glyph shapes
3 - neither fill nor stroke glyph shapes (invisible)
4 - fill and add to path for clipping glyph shapes
5 - stroke glyph shapes and add to path for clipping
6 - fill, then stroke glyph shapes and add path for clipping
7 - add glyph shapes to path for clipping
如果我使用“填充”模式,OCR 中的文本在底层扫描图像上看起来可能不太好看。因此我更喜欢“描边”变体。所以我只需将上面的行更改为
1 Tr
看到这个修改后的 PDF,我不喜欢它,因为默认线宽对我来说太粗了。此外,轮廓线的颜色是黑色(默认);我更喜欢红色,这样与原始扫描的形状形成对比。因此,我在此行的前面添加了一些代码,将线宽设置为四分之一点:
.25 w
还有一些将描边颜色设置为红色:
1 0 0 RG
现在完整内容如下:
.25 w 1 0 0 RG 1 Tr
就这样。
笔记,我们的小操作已经损坏了文件,因为它的“TOC”(技术术语:它的xref
表格)现在不再有效。Acrobat Reader 或 Acrobat Professional 仍然会打开它(甚至不会抱怨)并默默地“修复”文件的 xref 部分。其他 PDF 查看器可能会拒绝该文件,但目前我们不在乎……
以下是结果截图: (第一个屏幕截图放大到窗口宽度。) (第二张截图放大到 800%。)
红色轮廓就是现在可见的扫描文本,正如我们想要的那样。
我对这两个文件执行了上述相同的程序来自_abbyy.pdf和after_ghostscript.pdf。我在两个不同的 Acrobat Reader 实例中打开了这两个结果。如果我们让它们都缩放到相同的值并最大化两个窗口,那么就可以通过 轻松在两个文件之间切换视图[alt]+[tab]
。这是一种揭示两个 PDF 文件之间最细微的渲染差异的好方法。
我的结果是:Ghostscript (v9.02) 对此文件的输入和输出之间甚至没有一个像素的差异。但是,如果您想复制粘贴文本,就会有很大差异……
答案3
来自 Ghostscript 错误报告:
http://bugs.ghostscript.com/show_bug.cgi?id=692206
我现在已经能够重现该问题,它不是 8.71 的回归,而是一个进步(也是 Adobe 的变化)。
8.71 附带了一个错误,导致它写入无效的 ToUnicode CMap。误导性和矛盾的 Adobe 文档导致 CMap 被写成 CMap,而事实上 ToUnicode CMap 有其自己的、不兼容的规则。
ToUnicode CMap 通常仅用于搜索和复制/粘贴。顾名思义,它们用于将字符代码映射到 Unicode 代码点。8.71 PDF 文件中的 ToUnicode CMap 未被使用,因为它无效,更高版本中的 ToUnicode CMap 有效,并且已知 Acrobat 会使用它。
似乎在 Acrobat Reader 9.2 及之前的版本中,ToUnicode 数据的存在没有区别。在 9.2 之后的某个时间点,搜索机制发生了变化,Acrobat 似乎根据是否存在 ToUnicode CMap 使用两种不同的机制。在 9.2 之后我无法访问 Acrobat Pro,而且最近才安装了 Reader X,两者之间没有任何区别。
“无 Unicode”方法适用于所有版本的 Acrobat,而“Unicode”方法在较新版本上则失败。
我通过在 FontDescriptor 中引用 ToUnicode CMap 来显示这一点。如果需要,我可以提供各种文件,但它们很大,因为它们是解压的。
由于搜索是 PDF 中的启发式搜索,因此无法保证一定的结果。行为的改变是由于 Acrobat 而不是 Ghostscript,而 Ghostscript 中的改变是为了修复一个真正的错误,因此是一种进步,而不是倒退。
答案4
为了检查这个问题是否与字体的“嵌入性”有关,我在 Linux 上进行了另一次转换。我使用这个命令行让 Ghostscript 嵌入使用的字体:
gs \
-o after_ghostscriptonlinux.pdf \
-sDEVICE=pdfwrite \
-dPDFSETTINGS=/prepress \
-sEmbedAllFonts=true \
from_abbyy.pdf
Ghostscript 将显示以下输出:
GPL Ghostscript SVN PRE-RELEASE 9.02 (2011-02-07)
Copyright (C) 2010 Artifex Software, Inc. All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
Loading NimbusSanL-Regu font from %rom%Resource/Font/NimbusSanL-Regu... 2776276 1420923 2081124 778943 3 done.
Loading NimbusSanL-ReguItal font from %rom%Resource/Font/NimbusSanL-ReguItal... 2853416 1529123 2137980 831640 3 done.
Loading NimbusSanL-Bold font from %rom%Resource/Font/NimbusSanL-Bold... 2970748 1643508 2194836 886454 3 done.
Ghostscript 嵌入了名为NimbusSanL. 所以不再Arial 字体,Acrobat Reader 用它来替代缺失的 Helvetica 来在屏幕上渲染(另请参阅上面 user701996 的评论)。请注意,Ghostscript 会在嵌入后立即将该字体重命名为 Helvetica。但这不是问题,因为 NimbusSanL 是作为 Helvetica 的克隆创建的...
但是,即使对于此输出 PDF,从 Acrobat Reader 复制粘贴也无法正常工作。尽管 Reader 不再需要使用 ArialMT 来替代 Helvetica。Reader 现在使用嵌入的 NimbusSanL/Helvetica 克隆。
到目前为止,我们已经确定了有关从 Acrobat Reader 或 Acrobat Professional 复制粘贴文本的以下事实:
- Ghostscript 的输出v9.02 不起作用对于这个文件来说已经足够好了。
- 无论字体是否由 GS 嵌入,情况都是如此。
Windows XP 上的 GS 和 Linux 上的 GS 都是这种情况。
Ghostscript 的输出v8.71 确实有效对于这个文件来说已经足够好了。
- 无论字体是否由 GS 嵌入,情况都是如此。
Windows XP 上的 GS 和 Linux 上的 GS 都是这种情况。
即使复制粘贴的输出出现问题,另存为文本...做。
我仍然不明白为什么会这样。但很明显,这似乎是 Ghostscript 从 v8.71 到 9.02 的某种(可能是轻微的)退化。
现在让我们使用其他 PDF 查看软件来尝试处理“关键”的 PDF:
- Linux 上 Wine 中的 Adobe Reader X:与 v9.4.4 一样,复制粘贴被破坏。
- Linux 上的 Evince v2.32.2:复制粘贴有效。
- Windows XP Prof 上的 PDFXChange Viewer 2.5(build 191):复制粘贴有效。
- Linux 上的 MuPDF 阅读器 0.8:不知道如何复制和粘贴——但“搜索”功能可以完美运行。
- 在 Linux 上发现了名为“PDF Viewer 0.1.7”的东西:复制粘贴可以正常工作。
- Linux 上 Wine 中的 SumatraPDF v1.5:复制粘贴有效。
- Windows XP 上的 SumatraPDF v1.5.1:复制粘贴有效。
- Windows XP 上的 FoxitReader 4.3.1.0113:复制粘贴有效。
- Linux 上 Wine 内的 Nitro PDF 阅读器:复制粘贴有效。
请注意,所有“可用”的 PDF 阅读器之间仍然存在一些非常小的差异,我的结论是复制粘贴有效。例如这里缺少一个破折号,或者那里单词之间有两个空格,还有其他类似的问题...我目前无法解释为什么会出现这种情况,但这可能是 Adobe 产品(没有可用于此文件的复制粘贴功能)与“世界其他地方”之间存在巨大差距的根本原因。