我正在尝试从某些 pdf 文件中删除矢量。 Ghostscript (gs) 使用 -dFILTERVECTOR 选项可以正常工作:
gswin64c -o "test_out.pdf" -sDEVICE=pdfwrite -dFILTERVECTOR "test.pdf"
但是当我在大型 pdf 文件(大于 100MB,超过 1000 页)上运行此命令时,我收到这样的错误,并输出一个空白 pdf 文件:
Page 1139
Page 1140
**** Error: can't process embedded font stream,
attempting to load the font using its name.
Output may be incorrect.
Querying operating system for font files...
Substituting font Courier for AVFCLE+CourierNewPSMT.
Can't find (or can't open) font file %rom%Resource/Font/NimbusMonoPS-Regular.
Can't find (or can't open) font file NimbusMonoPS-Regular.
Can't find (or can't open) font file %rom%Resource/Font/NimbusMonoPS-Regular.
Can't find (or can't open) font file NimbusMonoPS-Regular.
Didn't find this font on the system!
Unable to substitute for font.
**** Error reading a content stream. The page may be incomplete.
Output may be incorrect.
Error: /dictfull in --filter--
Operand stack:
--dict:7/15(L)-- --nostringval-- 9 F_2 26049 11 FontObject --dict:10/18(L)-- false --dict:4/12(L)-- --nostringval-- --nostringval--
Execution stack:
%interp_exit .runexec2 --nostringval-- filter --nostringval-- 2 %stopped_push --nostringval-- filter filter false 1 %stopped_push 1992 1 3 %oparray_pop 1991 1 3 %oparray_pop 1979 1 3 %oparray_pop 1980 1 3 %oparray_pop filter filter 1141 1 1277 filter %for_pos_int_continue 1983 1 7 %oparray_pop filter filter filter filter %array_continue filter filter filter filter filter %array_continue 1827 13 10 %oparray_pop
Dictionary stack:
--dict:734/1123(ro)(G)-- --dict:1/20(G)-- --dict:80/200(L)-- --dict:80/200(L)-- --dict:133/256(ro)(G)-- --dict:317/325(ro)(G)-- --dict:33/64(L)-- --dict:6/9(L)-- --dict:6/20(L)-- --dict:9/15(L)--
Current allocation mode is local
GPL Ghostscript 9.27: Unrecoverable error, exit code 1
Unrecoverable error: VMerror in --.systemvmSFD--
Operand stack:
--nostringval-- --nostringval-- 0
GPL Ghostscript 9.27: ERROR: A pdfmark destination page 1277 points beyond the last page 1139.
问题似乎与第1140页的字体问题有关。但实际上,如果我将文件视为2个部分,则每个部分都可以正常工作,没有问题:
第 1 部分:从 1 到 1000 页
gswin64c -o "test_part1.pdf" -sDEVICE=pdfwrite -dFILTERVECTOR -sPageList=-1000 "test.pdf"
第二部分:从1001到最后一页(1900左右)
gswin64c -o "test_part2.pdf" -sDEVICE=pdfwrite -dFILTERVECTOR -sPageList=1001- "test.pdf"
所以,如果我理解得好的话,似乎与页数或pdf文件的大小更有关系
生成上述结果的pdf文件是私人文件,所以我无法上传它们。但我创建了一个 175MB 的测试 pdf 文件(点击此处下载),它给出了类似的问题:
Page 1345
**** Error reading a content stream. The page may be incomplete.
Output may be incorrect.
**** Error: File did not complete the page properly and may be damaged.
Output may be incorrect.
Page 1346
*** ERROR: The font BCDEEE+Calibri is damaged and cannot be used. Switching to a
last-ditch fallback, text may not render correctly, or at all.
**** Error reading a content stream. The page may be incomplete.
Output may be incorrect.
**** Error: File did not complete the page properly and may be damaged.
Output may be incorrect.
Page 1347
**** Error: can't process embedded font stream,
attempting to load the font using its name.
Output may be incorrect.
Substituting font Helvetica for BCDEEE+Calibri.
**** Error reading a content stream. The page may be incomplete.
Output may be incorrect.
**** Error: File did not complete the page properly and may be damaged.
Output may be incorrect.
Page 1348
Error: /VMerror in --filter--
VM status: 4 43671928 45257592
Current allocation mode is local
Last OS error: 2
GPL Ghostscript 9.27: Unrecoverable error, exit code 1
知道我在 Windows 10 上使用最新版本的 Ghostscript 9.27 64 位,有解决此问题的想法吗?
我怀疑问题与-dFILTERVECTOR的使用无关。如果您尝试将其从命令行中删除会发生什么?
您还应该尝试最新的 Ghostscript 代码(尚未发布),它解决了可能存在的相关问题。
此提交解决了此错误报告,这与您在此处报告的内容类似。我怀疑你只是耗尽了内存(或者至少是 Ghostscript 可寻址的内存)。
测试该文件后,在 17452 个页面之后,它耗尽了我的内存,使用了 2GB(并且不需要 FILTERVECTOR 开关,正如我所预期的那样)。
这个问题没有解决办法。 pdfwrite 设备需要在内存中保留大量内容,以保持合理的处理性能。
此外,您的文件在每个页面上嵌入每种字体的新副本。即使这些字体都有相同的名称,我们也必须将它们视为唯一的字体。如果不这样做就意味着我们可能使用错误的字体。
因此您的文件有 1980 页,每页有 5 种字体,即 9,900 种字体。我强烈怀疑将所有这些字体副本保存在内存中的开销才是消耗这么多的原因。快速估计(查看解压缩的字体流大小)是字体本身就会占用大约 792MB 内存。一旦添加编码、宽度数组等,这很容易成为内存使用的主要来源。