如何使用 ghostscript 在多页 pdf 中裁剪第 3 页和第 4 页

How do I crop pages 3&4 in a multipage pdf using ghostscript

我想在多页 pdf 中只裁剪一些页面,保留所有页面,一些裁剪,另一些不裁剪。我尝试了以下但它 "deletes" 非裁剪页面...

gswin64.exe -o cropped.pdf -sDEVICE=pdfwrite  -dFirstPage=3 -dLastPage=4 -c "[/CropBox [24 72 1559 1794]" -c " /PAGES pdfmark" -f input.pdf

我看过关于奇数页和偶数页不同裁剪的帖子,但我不知道如何将其应用于多页文档中的特定页面。

gswin64.exe -o cropped.pdf -sDEVICE=pdfwrite -c "<</EndPage {0 eq {2 mod 0 eq {[/CropBox [0 0 1612 1792] /PAGE pdfmark true}{[/CropBox [500 500 612 792] /PAGE pdfmark true} ifelse}{false}ifelse}>> setpagedevice" -f input.pdf

这会根据第二个裁剪框的设置裁剪所有页面。如果有人对大边距感到疑惑……我会用它来做大图。 我还尝试用一些运算符来替代某些运算符,使其仅将裁剪应用于特定页码:"sub 4" 而不是“2 mod”是一种仅在当前页面时才达到“0 eq”条件的尝试人数达到4.

首先,Ghostscript 和 pdfwrite 设备不'modify' 输入 PDF 文件。对于普通读者;标准讲义在这里,如果你之前看过可以跳过下面的段落。

其工作方式是将输入文件完全解释为一系列图形基元,然后发送到设备。渲染设备然后调用图形库将图元渲染为位图,然后输出。高级(矢量)设备,例如 pdfwrite,将原语转换为某种高级页面描述语言的等效操作,并发出它。

因此,当您 select -dFirstPage 和 -dLastPage 时,对于您选择处理的输入文件,这些 页。所以 pdfwrite 不是 'deleting' 你的页面,你从来没有把它们发送到设备上。

现在,Ghostscript 是一个 PostScript 解释器,因此它的行为会受到编写 PostScript 程序的影响。在你的情况下,你可能想要实际处理 all 页面(所以删除 -dFirstPage 和 -dLastPage),但只在 selected 页面上写 pdfmark。

执行此操作的方法是通过 BeginPage 或 EndPage 过程。如果您在此处或在 PostScript 标记中搜索,您会找到许多示例。从根本上说,这两个过程都是用原因代码和到目前为止的页数调用的。

根据记忆,您需要检查原因代码是否为 2。如果是,那么您需要检查页数,它符合您的条件(在本例中,计数为 3 或 4) , 执行 /PAGE pdfmark。在任何情况下,您都希望 return 'true' 以便发出页面。

[此处添加编辑]

嗯,好的,我明白了。发生的事情是 PDF 解释器正在调用 'setpagedevice' 来设置每个页面的页面大小,以防页面大小发生变化。问题是这每次都会将页数重置为 0。

现在,我通常不会建议以下内容,因为它依赖于 Ghostscript 的 PDF 解释器的一些未记录的方面。但是,我碰巧知道 PDF 解释器使用名为 /Page# 的命名对象在内部跟踪页码。

所以,如果我把你写的代码,稍微修改一下:

<<
  /EndPage {
    0 eq {
      pop /Page# where {
        /Page# get
        3 eq {
          (page 3) == flush
          [/CropBox [0 0 1612 1792] /PAGE pdfmark 
          true
        }
        {
          (not page 3) == flush
          [/CropBox [500 500 612 792] /PAGE pdfmark
          true
        } ifelse
      }{
        true
      } ifelse
    }
    {
      false
    }
    ifelse
  }
>> setpagedevice

有几点需要注意;那里有一些调试,带有'== flush'的行在后台通道上打印出一些东西,所以你知道每个页面是如何处理的。如果 /Page# 没有被定义,那么代码只是简单地保留一切,这只是一些基本的安全第一的东西。

我没有在命令行上输入所有这些(它也失去了缩进并且难以阅读)我把它放在一个名为 test.ps 的文件中,然后调用 GS 为:

gswin32c -sDEVICE=pdfwrite -sOutputFile=out.pdf test.ps input.pdf

这不是世界上最简洁的解决方案,但对我有用。