pdf - 合并PDF时,Ghostscript会跳过字符

标签 pdf merge ghostscript

在Ubuntu上使用Ghostscript(8.71版)合并使用wkhtmltopdf创建的PDF文件时遇到问题。

我在随机情况下遇到的问题是,某些字符在合并过程中丢失,并在合并的PDF中被任何内容(或空格)所取代。如果我看原始的PDF看起来不错,但是合并后缺少一些字符。

请注意,一个丢失的字符(例如数字9或字母a)可能会在文档中的某个位置丢失,但在文档中的其他位置显示得很好,因此这不是显示它或出现字体问题的问题。

我正在使用的命令是:

gs \
   -q \
   -dNOPAUSE \
   -sDEVICE=pdfwrite \
   -sOutputFile=/tmp/outputfilename \
   -dBATCH \
    /var/www/documents/docs/input1.pdf \
    /var/www/documents/docs/input2.pdf \
    /var/www/documents/docs/input3.pdf 

任何其他经历过此事,甚至更好地知道解决方案的人?

最佳答案

如果嵌入式字体子集的名称相同,但是这些子集的实际内容不同(包含不同的字形集),我已经看到这种情况的发生。
检查所有输入文件中使用的字体。为此使用Poppler的pdffonts实用程序:

 for i in input*.pdf; do
     pdffonts ${i} | tee ${i}.pdffonts.txt
 done
查找每个PDF中使用的字体名称。
我的理论/赌注是您看到不同的输入文件使用相同的字体名称(名称类似于BAAAAA+ArialMT)。
用于子字体的BAAAAA+字体名称前缀应该是随机的(尽管官方规范对此并不十分清楚)。但是,某些应用程序使用可预测的前缀,从BAAAAA+CAAAAAA+DAAAAA+等开始。(OpenOffice.org和LibreOffice为此而臭名昭著)。这意味着在至少使用一个子集字体的每个文件中都会使用前缀BAAAAA+ ...
很容易发生您的输入文件没有使用完全相同的字符子集的情况。但是,使用的相同名称可能会使Ghostscript认为字体确实是相同的。它(错误地)“优化”了合并的PDF,并且仅嵌入了两个字体实例之一(两者都具有相同的名称,例如BAAAAA+Arial)。但是,此实例可能不包含某些字形,而这些字形是其他实例的一部分。
这导致合并输出中缺少某些字符。
我知道,最新版本的Ghostscript对其字体处理代码进行了大修。尝试使用Ghostscript v9.06(迄今为止的最新版本)也许会更幸运。
我对更详细地调查这一点非常感兴趣。如果您可以提供输入文件的样本(以及GS v8.70给出的合并输出),我可以测试一下它在v9.06中是否更好。
可以做些什么来避免这个问题
  • 尝试始终将字体作为完整的字体而不是的子集嵌入:
  • 我不知道在使用wkhtmltopdf时是否以及如何控制完全字体嵌入。
  • 如果您是从Libre/OpenOffice生成输入PDF的,那么您将很不走运,并且无法对其进行控制。
  • 如果使用Acrobat生成输入的PDF,则可以在Distiller设置中调整字体嵌入的详细信息。
  • 如果Ghostscript生成您的输入PDF,则用于强制执行完整字体嵌入的命令行参数为:gs -o output.pdf -sDEVICE=pdfwrite -dSubsetFonts=false input.file

  • 某些类型的字体不能完全嵌入,而只能部分嵌入(TrueType,Type3,CIDFontType0,CIDFontType1,CIDFontType2)。看到this answer来问“为什么Acrobat Distiller不能完全嵌入所有字体?”更多细节。
  • 仅在您确定没有其他人可以看到或打印或使用您的单个输入文件时,才执行以下操作:根本不嵌入字体-仅在与Ghostscript合并时才嵌入从输入中获得最终结果PDF 。
  • 我不知道在使用wkhtmltopdf时是否以及如何控制没有字体嵌入。
  • 如果您是从Libre/OpenOffice生成输入PDF的,那么您将很不走运,并且无法对其进行控制。
  • 如果使用Acrobat生成输入的PDF,则可以在Distiller设置中调整字体嵌入的详细信息。
  • 如果Ghostscript生成您的输入PDF,则用于防止字体嵌入的命令行参数为:gs -o output.pdf -sDEVICE=pdfwrite -dEmbedAllFonts=false -c "<</AlwaysEmbed [ ]>>setpagedevice" input.file

  • 某些类型的字体不能完全嵌入,而只能部分嵌入(Type3,CIDFontType1)。看到this answer来问“为什么Acrobat Distiller不能完全嵌入所有字体?”更多细节。
  • 不使用Ghostscript,而是使用pdftk合并PDF。在合并PDF时, pdftk比Ghostscript(至少是pdftk的较旧版本)更``笨拙'',并且这种笨拙可能是一个优势...

  • 更新
    再次回答,但这次更明确(在下面的注释中,@ sacohe后面是另一个问题。在许多(不是全部)情况下,以下过程将起作用:
  • 在Ghostscript(最好是9.0x系列的最新版本)的帮助下,重新“提取”输入的PDF文件。
  • 使用的命令是这样的(或类似的):gs -o redistilled-out.pdf -sDEVICE=pdfwrite input.pdf

  • 然后,即使输入PDF对不同的字体(子集)使用了相同的名称前缀,结果输出PDF也应使用不同的(唯一)字体名称前缀。
    当我处理原始问题的作者“Mr R”提供给我的原始输入文件的样本时,此过程对我有用。修复之后,“跳过字符问题”在最终结果中消失了(从固定输入文件创建的合并PDF)。

    关于pdf - 合并PDF时,Ghostscript会跳过字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12806911/

    相关文章:

    javascript - 选择 rxjs 中重复的第一项

    python - 合并 Pandas Dataframes 时如何仅使用第一个匹配项?

    pdf - PDF 规范中 "base 14"字体的字体度量

    python - 使用 Python 自动下载嵌入式 PDF 文件

    python - pisa html 到 pdf 问题,希腊重音字母与 django 一起使用

    java - 将多行电子表格转换为 pdf 的简洁方法

    Git branch checkout 说虽然我的工作目录是干净的,但文件将被覆盖

    pdf - 如何使用pdfbox api根据数字签名的有效性显示不同的图像?

    html - 使用 ghostscript 缩小 PDF 会导致图像不对齐

    linux - Linux命令行上的PDF比较