通过Ghostscript运行后,PDF在所有单词上都有一个额外的空白


10

该PDF由Abbyy Finereader 10制作:

http://ebooks.zeitr.org/from_abbyy.pdf

您可以复制并粘贴第一句话,并获得以下(非常好的)文本结果:

德国外滩体育馆20世纪1955年11月号,德国体育馆和德国私人体操馆。

用Ghostscript 9.02(64位Windows)进行一些处理后,我得到了这个文件:

http://ebooks.zeitr.org/after_ghostscript.pdf

现在,第一个句子看起来很奇怪-每个单词的最后一个字符之前都有一个多余的空格。

Der»Bun d Deutsche r GymnastikSchulleiter«乌姆20。195年11月5日在莱斯特林纳州的私人参议院举行的选举中,阿尔萨斯里克人民阵线的胜利。

这具有主要的负面影响,即您无法在Acrobat Reader中搜索整个单词。我可以通过为Ghostscript设置以下最小参数来重现效果:

-sDEVICE=pdfwrite ^
-dBATCH ^
-dNOPAUSE ^
-sstdout="myStdOut" ^
-sOutputFile="myDestFile.pdf" ^
 mySourceFile.pdf

有任何想法吗?


@Erwin Jurschitza:您是否愿意将from_abbyy.pdf文件的链接保留一段时间,这样即使几个月后仍可以检索到它?
Kurt Pfeifle

@pipitas:没问题,它在Amazon S3上。

Answers:


8

我发现这是一个有趣的问题,并仔细查看了...

首先,我使用qpdf命令行工具解压缩PDF数据流,以便更好地查看两个文件的源代码:

qpdf.exe ^
   --qdf ^
     from_abbyy.pdf ^
     qdf--from_abbyy.pdf

qpdf.exe ^
   --qdf ^
     after_ghostscript.pdf ^
     qdf--after_ghostscript.pdf

看一下插入多余空间的第一个事件(原始字符串“ Bund Deutscher Gymnastik-Schulleiter”变成“ Bun d Deutsche r GymnastikSchulleiter”),我发现以下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文本矩阵)运算符,并且还增加了一个额外的……我不知道为什么。我将向Ghostscript的bugzilla [*]提交错误报告,看看他们是否有兴趣解决它。Td2.16501 0 Td

但是请注意,如果我使用Linux Acrobat Reader 9.4.2并使用菜单操作“ File-> Save as Text ...”,则不会发生此问题。在这种情况下,没有其他空格(但是有一些额外的换行符)。在Linux上,文本也无法正确搜索,并且在执行copy'n'paste ... 时还会显示多余的空格。


[*]完成后,我将在此处更新Bug号。


更新:

在考虑了有关替换后的Tm运算符的更多信息之后,我现在认为这不应成为问题的根源。

当意识到这一点时,我确实尝试使用Ghostscript v8.71而不是v9.02进行转换。我该怎么说呢?v8.71输出不会发生copy'n'paste问题!

这意味着:Ghostscript 9.02中存在一个问题,而该问题在8.71中不存在。它最有可能与输出PDF中嵌入的字体指标有关。因为上面引用的PDF片段在v8.71输出中与v9.02输出中相同....

更新2:

Ghostscript的bugzilla中的错误输入网址:

更新3:

此错误似乎确实已得到修复。我没有用我再次测试过的Ghostscript版本发生这种情况:当前的Git(v9.10GIT)或Ghostscript v9.06。


@pipitas:非常感谢您对此进行分析!

5

如果将带有文本的页面扫描到PDF中并在其上运行OCR应用程序,则文本将添加到页面中,但是“文本呈现模式”设置为不可见。它在那里,但不呈现在屏幕上(或打印在纸上)。您看到或打印的是原始扫描图像。

我们如何使不可见的文字可见?

好吧,我们可以编辑PDF ...将文本渲染设置为不可见的PDF代码是这样的:

3 Tr

您无法在原始from_abbyy.pdffrom_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仍将打开它(甚至不会抱怨)并以静默方式“修复”文件的外部参照部分。其他PDF查看器可能会拒绝该文件,但目前我们不在乎...

以下是结果的 缩放到窗口宽度 屏幕截图:(第一个屏幕截图放大到窗口宽度。) 放大至800% (第二个屏幕截图放大到800%。)

红色轮廓是所扫描的文本,现在可以看到,就像我们想要的一样。

我对from_abbyy.pdfafter_ghostscript.pdf这两个文件执行了与上述相同的过程。我在2个不同的Acrobat Reader实例中打开了两个结果。如果我们使它们都缩放到相同的值并最大化两个窗口,则可以通过轻松在两个文件之间切换视图[alt]+[tab]。这是揭示两个PDF文件之间最好的渲染差异的好方法。

我的结果是:Ghostscript(v9.02)输入和此文件的输出之间甚至没有一个像素不同。但是,如果您要复制'n'粘贴文本,则有很大的不同...


1

我看不到所描述的问题。我使用Acrobat Professional 9.0打开了“之后” PDF文件,然后正确复制并粘贴了文本。

Ghostscript完全解释PDF文件,并根据其解释生成一个新的PDF文件,它与原始文件没有任何关系,只不过它记录了文本的位置。

由于PDF具有丰富的功能集,因此可以使用多种不同的方法将字符放置在同一位置。因此,GS生成PDF文件的方式本身没有任何错误或意外。

鉴于文本可以正确保存,这是Acrobat启发式方法的问题,它决定了当作为连续ASCII处理时,两个“附近”字符是否相邻或之间是否有空格。

我不认为问题可能是嵌入式字体指标,原因很简单,即未嵌入字体:-)使用的字体是Helvetica,它没有嵌入文档中,所以Acrobat(至少对我而言)使用ArialMT。请注意,“原始” PDF文件也不包含字体。

我最终将查看报告的错误,但是不会很快,并且我怀疑我们是否可以(或将要)做任何事情。在我看来,这是试探法的必然结果。不过,这可能有助于嵌入字体,以便至少使它们保持一致。


@ user701996:有趣-Acrobat Pro 9.0没问题吗?我的Acrobat Reader X(10.0.1,Windows)有问题。

@ user701996:我在Acrobat Professional 9.4.4中打开了该文件。之后文件的复制粘贴不起作用。另存为文本...但没有工作....
库尔特Pfeifle

@ user701996:即使未嵌入字体,字体指标也为。嗯,除非字体是“ Base 14”之一。...所以您在这种情况下可能是对的。我会仔细看。
Kurt Pfeifle

@ user701996:您听起来像您是Ghostscript人之一。你是?
Kurt Pfeifle

1

来自以下位置的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,我之间什么也没有。

“ no Unicode”方法不适用于所有版本的Acrobat,“ Unicode”方法不适用于较新版本。

我通过在FontDescriptor中对ToUnicode CMap的引用使用白色间距来显示这一点。如果需要,我可以提供各种文件,但是由于它们已解压缩,因此它们很大。

由于搜索是PDF中的启发式工作,因此无法保证结果。行为上的变化是由于Acrobat而不是Ghostscript而引起的,而Ghostscript的变化是为了修复一个实际的错误,因此是一个进度,而不是一个回归。


0

为了检查该问题是否与字体的“嵌入度”有关,我在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的字体家族的字体。因此,不再有ArialMT了,就像Acrobat Reader在屏幕上渲染时使用的那样,可以代替丢失的Helvetica(另请参见上面user701996的评论)。请注意,Ghostscript一旦嵌入,它将立即将该字体重命名为Helvetica。但这不是问题,因为NimbusSanL是作为Helvetica的克隆而创建的...

但是,即使对于此输出PDF,从Acrobat Reader复制'n'paste也无法正常工作。尽管读者不再需要使用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(内部版本191)Prof:复制粘贴即可。
  • 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 Reader:复制粘贴功能。

请注意,所有“正常” PDF阅读器之间还有其他但很小的区别,我的判断是“ 复制”粘贴作品。例如,这里缺少破折号,或者单词之间的间隔加倍,以及其他类似的事情...目前我还没有解释为什么会这样,但是可能是相同的根本原因,为什么Adobe产品之间存在巨大差异(此文件没有有效的复制粘贴),一个避难所,另一个“世界其他地方”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.