【问题标题】:Ghostscript fails to convert some PDFsGhostscript 无法转换某些 PDF
【发布时间】:2016-04-21 00:18:12
【问题描述】:

背景

一段时间以来,我一直在使用 Ghostscript 将 PDF 转换为 PNG 和 GIF。

我在 RHEL6 Unix 上通过 PHP 中的 exec 命令执行此操作:

exec("/usr/bin/gs -dNOPAUSE -dBATCH -dQUIET -sDEVICE=png256 -sOutputFile=\"".$out."\" ".$in, $return);

$out 和 $in 解析为 PDF 输入和 PNG 输出的路径。

但是,某些 PDF 似乎不再转换,出现以下错误:

Error: /invalidaccess in --run--
Operand stack:
--dict:8/17(L)-- F2 85.117 --dict:6/6(L)-- --dict:6/6(L)-- CenturyGothic --dict:11/12(ro)(G)-- --nostringval-- CIDFontObject --dict:6/6(L)-- --dict:6/6(L)-- 14280 --dict:6/6(L)-- --nostringval-- PDFCIDFontName CenturyGothic
Execution stack:
%interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- false 1 %stopped_push 1862 1 3 %oparray_pop 1861 1 3 %oparray_pop 1845 1 3 %oparray_pop --nostringval-- --nostringval-- 2 1 2 --nostringval-- %for_pos_int_continue --nostringval-- --nostringval-- --nostringval-- --nostringval-- %array_continue --nostringval-- false 1 %stopped_push --nostringval-- %loop_continue --nostringval-- --nostringval-- --nostringval-- --nostringval-- --nostringval-- --nostringval-- %array_continue --nostringval-- --nostringval-- --nostringval-- --nostringval-- --nostringval--
Dictionary stack:
--dict:1149/1684(ro)(G)-- --dict:1/20(G)-- --dict:75/200(L)-- --dict:75/200(L)-- --dict:106/127(ro)(G)-- --dict:286/300(ro)(G)-- --dict:22/25(L)-- --dict:4/6(L)-- --dict:21/40(L)-- --dict:1/1(ro)(G)--
Current allocation mode is local

我的 Ghostscript 版本是:

GPL Ghostscript 9.16 (2015-03-30)
Copyright (C) 2015 Artifex Software, Inc.  All rights reserved.
Usage: gs [switches] [file1.ps file2.ps ...]
Most frequently used switches: (you can use # in place of =)
 -dNOPAUSE           no pause after page   | -q       `quiet', fewer messages
 -g<width>x<height>  page size in pixels   | -r<res>  pixels/inch resolution
 -sDEVICE=<devname>  select device         | -dBATCH  exit after last file
 -sOutputFile=<file> select output file: - for stdout, |command for pipe,
                                         embed %d or %ld for page #
Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PostScriptLevel3 PDF
Default output device: bbox
Available devices:
   alc1900 alc2000 alc4000 alc4100 alc8500 alc8600 alc9100 ap3250 appledmp
   atx23 atx24 atx38 bbox bit bitcmyk bitrgb bitrgbtags bj10e bj10v bj10vh
   bj200 bjc600 bjc800 bjc880j bjccmyk bjccolor bjcgray bjcmono bmp16 bmp16m
   bmp256 bmp32b bmpgray bmpmono bmpsep1 bmpsep8 ccr cdeskjet cdj1600 cdj500
   cdj550 cdj670 cdj850 cdj880 cdj890 cdj970 cdjcolor cdjmono cdnj500 cfax
   chp2200 cif cljet5 cljet5c cljet5pr coslw2p coslwxl cp50 declj250 deskjet
   devicen dfaxhigh dfaxlow dj505j djet500 djet500c dl2100 dnj650c epl2050
   epl2050p epl2120 epl2500 epl2750 epl5800 epl5900 epl6100 epl6200 eplcolor
   eplmono eps2write eps9high eps9mid epson epsonc escp escpage faxg3
   faxg32d faxg4 fmlbp fmpr fpng fs600 gdi hl1240 hl1250 hl7x0 hpdj1120c
   hpdj310 hpdj320 hpdj340 hpdj400 hpdj500 hpdj500c hpdj510 hpdj520 hpdj540
   hpdj550c hpdj560c hpdj600 hpdj660c hpdj670c hpdj680c hpdj690c hpdj850c
   hpdj855c hpdj870c hpdj890c hpdjplus hpdjportable ibmpro ijs imagen
   inferno ink_cov inkcov itk24i itk38 iwhi iwlo iwlq jetp3852 jj100 jpeg
   jpegcmyk jpeggray la50 la70 la75 la75plus laserjet lbp310 lbp320 lbp8
   lex2050 lex3200 lex5700 lex7000 lips2p lips3 lips4 lips4v lj250 lj3100sw
   lj4dith lj4dithp lj5gray lj5mono ljet2p ljet3 ljet3d ljet4 ljet4d
   ljet4pjl ljetplus ln03 lp1800 lp1900 lp2000 lp2200 lp2400 lp2500 lp2563
   lp3000c lp7500 lp7700 lp7900 lp8000 lp8000c lp8100 lp8200c lp8300c
   lp8300f lp8400f lp8500c lp8600 lp8600f lp8700 lp8800c lp8900 lp9000b
   lp9000c lp9100 lp9200b lp9200c lp9300 lp9400 lp9500c lp9600 lp9600s
   lp9800c lps4500 lps6500 lq850 lxm3200 lxm5700m m8510 mag16 mag256
   md1xMono md2k md50Eco md50Mono md5k mgr4 mgr8 mgrgray2 mgrgray4 mgrgray8
   mgrmono miff24 mj500c mj6000c mj700v2c mj8000c ml600 necp6 npdl nullpage
   oce9050 oki182 oki4w okiibm oprp opvp paintjet pam pamcmyk32 pamcmyk4 pbm
   pbmraw pcl3 pcx16 pcx24b pcx256 pcx2up pcxcmyk pcxgray pcxmono pdfwrite
   pgm pgmraw pgnm pgnmraw photoex picty180 pj pjetxl pjxl pjxl300 pkm
   pkmraw pksm pksmraw plan plan9bm planc plang plank planm plib plibc plibg
   plibk plibm png16 png16m png256 png48 pngalpha pnggray pngmono pnm pnmraw
   ppm ppmraw pr1000 pr1000_4 pr150 pr201 ps2write psdcmyk psdcmykog psdrgb
   pxlcolor pxlmono r4081 rinkj rpdl samsunggdi sgirgb sj48 spotcmyk st800
   stcolor sunhmono t4693d2 t4693d4 t4693d8 tek4696 tiff12nc tiff24nc
   tiff32nc tiff48nc tiff64nc tiffcrle tiffg3 tiffg32d tiffg4 tiffgray
   tifflzw tiffpack tiffscaled tiffsep tiffsep1 txtwrite uniprint xcf xes
   xpswrite
Search path:
   %rom%Resource/Init/ : %rom%lib/ :
   /usr/local/share/ghostscript/9.16/Resource/Init :
   /usr/local/share/ghostscript/9.16/lib :
   /usr/local/share/ghostscript/9.16/Resource/Font :
   /usr/local/share/ghostscript/fonts :
   /usr/local/share/fonts/default/ghostscript :
   /usr/local/share/fonts/default/Type1 :
   /usr/local/share/fonts/default/TrueType : /usr/lib/DPS/outline/base :
   /usr/openwin/lib/X11/fonts/Type1 : /usr/openwin/lib/X11/fonts/TrueType
Initialization files are compiled into the executable.

经过大量搜索和调试,我认为这与我的客户提供的原始 PDF 中嵌入的 CID 字体有关:

名称类型 emb sub uni 对象 ID

CenturyGothic TrueType 是 否 否 11 0

CenturyGothic CID TrueType 是 否 是 26 0

Arial-BoldMT CID TrueType 是 否 是 195 0

Arial-BoldMT TrueType 是 否 否 198 0

Arial-Black TrueType 是 否 否 586 0

所以,我重新制作了 PDF,它就像一个魅力。尽管我所做的只是在 Illustrator 中打开文件并重新保存,但嵌入的字体是不同的:

名称类型 emb sub uni 对象 ID

CDXNGM+CenturyGothic TrueType 是 是 否 94 0

CDXNGM+Arial-BoldMT TrueType 是 是 否 95 0

CDXNGM+Arial-Black TrueType 是 是 否 96 0

文件

失败的文件: https://www.dropbox.com/s/54hbdgtewplkrk0/failing.pdf?dl=0

工作文件: https://www.dropbox.com/s/x9uwbyjytjer1zy/working.pdf?dl=0

问题

  1. 我不确定为什么原始文件没有使用嵌入的 CID 字体,或者只是忽略它,因为它似乎甚至不需要?

  2. 为什么 Ghostscript 不产生字体错误而是无效访问错误?

  3. 有没有一种方法可以在转换之前在 PHP 中或通过 exec 去除 CID 字体?

  4. 有没有办法让 Ghostscript 忽略字体问题,尽其所能?

  5. 我可以对 ghostscript 做些什么来导致输出?

非常感谢任何帮助,谢谢。

【问题讨论】:

    标签: php linux pdf fonts ghostscript


    【解决方案1】:

    使用当前源代码、9.18 版9.16 版(全部从源代码构建),您的“失败”文件对我来说效果很好。

    这让我怀疑这是一个包装问题。各种 Linux 发行版包 GS 本身,并且这些包并不总是反映原始代码。打包者有时会添加自己的补丁,或更改 Ghostscript 的构建方式。特别是他们经常要求使用系统共享库而不是我们随 Ghostscript 一起提供的版本,并且这些版本已知可以工作。在这种情况下,例如,可能使用了不同版本的 FreeType。

    我建议您获取 Ghostscript 源代码,自行构建并进行测试。如果可行,那么您可以向维护 Red Hat 软件包的任何人投诉(但请确保您使用的是 latest 软件包,我似乎记得 Red Hat 通常是最新的并且您正在使用超过一年的版本)。

    所以回答你的问题:

    1. 需要所有字体。
    2. Ghostscript 正在产生一个无效访问错误(很可能),因为它试图更改已定义为“只读”的字体字典的内容。虽然这也是字体错误,但您得到的是最低级别的错误。
    3. 去除字体不是一个好的解决方案。首先是因为生成的图像会替换通常不正确的字体,其次是因为它很难做到。
    4. 对于 PDF 输入,如果 Ghostscript 可以忽略错误并继续,一般情况下会这样。这是一个致命错误。
    5. 是的,从源代码构建 Ghostscript。即使这不起作用,我们也能更好地帮助您。如果从规范源构建后它不起作用,请打开错误报告。

    我真的不认为值得就 CIDFonts 的优点或其他方面进行长时间的辩论,但这不太可能是问题的真正根源。

    【讨论】:

    • Ken,非常感谢您的认真回复。我将着手从源代码构建 9.18,看看它是否能解决问题,并让您知道我的进展情况。得到开发者的回复真是太好了,谢谢。
    • Ken,我从源代码构建了 GS 9.18,但仍然遇到同样的错误。我确实注意到 Resources 文件夹丢失了,所以我将它从源文件夹复制到 ge -h 说它应该在的位置,但仍然没有运气。
    • 好的,我将不得不建议您为此打开一份错误报告,并且我会请比我更了解 Linux 的人来调查它。请注意,您不需要 Resources 文件夹,因为默认情况下是将其构建到二进制文件中作为 ROM 文件系统。 gs -h 应该告诉你它在哪里,而不是文件夹必须去哪里。
    • 我已经在我的 Ubuntu 15.10 发行版上安装的 gs 9.16 上尝试了您的两个文件(working.pdf 和 failure.pdf),但都没有给出警告。能否在 PHP 环境之外重现问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多