首页 > 解决方案 > 从大型 pdf 文件中删除矢量时出现 Ghostscript 问题

问题描述

我正在尝试从一些 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"

第 2 部分:从 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 位,有什么想法可以解决这个问题吗?

标签: pdfghostscript

解决方案


我“怀疑”这个问题与 -dFILTERVECTOR 的使用无关。如果您尝试将其从命令行中删除,会发生什么?

您还应该尝试最新的 Ghostscript 代码(尚未发布),它解决了可能存在的相关问题。

提交解决了此错误报告,该报告与您在此处报告的内容相似。我怀疑您只是耗尽了内存(或者至少是 Ghostscript 可寻址的内存)。

[编辑]

测试了文件后,它在 17452 页之后使用 2GB 耗尽了我的内存(并且不需要 FILTERVECTOR 开关,正如我所料)。

对此没有解决方案。pdfwrite 设备需要在内存中保留大量内容以保持合理的处理性能。

此外,您的文件会在每一页上嵌入每种字体的新副本。即使这些字体中的每一个都具有相同的名称,我们也必须将它们视为唯一的字体。如果不这样做,就意味着我们可能会使用错误的字体。

所以你的文件有 1980 页,每页有 5 种字体,所以有 9,900 种字体。我强烈怀疑将所有这些字体副本保存在内存中的开销是非常消耗的。一个快速的估计(查看解压缩的字体流大小)是单独的字体将占用大约 792MB 的内存。一旦添加了编码、宽度数组等,这很容易成为内存使用的主要来源。


推荐阅读