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

Posted

技术标签:

【中文标题】如何使用 ghostscript 在多页 pdf 中裁剪第 3 和第 4 页【英文标题】:How do I crop pages 3&4 in a multipage pdf using ghostscript 【发布时间】:2016-10-27 19:05:28 【问题描述】:

我想只裁剪多页 pdf 中的一些页面,保留所有页面,一些被裁剪,另一些则没有。我尝试了以下方法,但它“删除”了未裁剪的页面......

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 ifelsefalseifelse>> setpagedevice" -f input.pdf

这会根据第二个 CropBox 的设置裁剪所有页面。如果有人想知道大边距...我将其应用于大型图纸。 我还尝试用一些运算符替换为仅将裁剪应用于某个页码:“sub 4”而不是“2 mod”是仅当当前页码达到 4 时才达到“0 eq”条件的一种尝试。

【问题讨论】:

Cropping a PDF using Ghostscript 9.01的可能重复 我的问题在你推荐的帖子中没有处理,我在问之前已经解决了。 【参考方案1】:

首先确定,Ghostscript 和 pdfwrite 设备不会“修改”输入的 PDF 文件。对于普通读者;标准讲座在这里,如果您已经阅读过,可以跳过以下段落。

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

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

现在,Ghostscript 是 PostScript 解释器,因此它的操作可能会受到编写 PostScript 程序的影响。在您的情况下,您可能希望实际处理 所有 页面(因此删除 -dFirstPage 和 -dLastPage),但只在选定页面上写入 pdfmark。

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

从内存中,您将要检查原因代码是否为 2。如果是,那么您要检查页数,并且它符合您的条件(在这种情况下,计数是 3 或 4),执行/PAGE pdf 标记。在任何情况下,您都希望返回 '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

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

【讨论】:

我尝试使用 Laura 提供的代码作为基础,它部分有效:here 只是它们总是根据第二个 CropBox 进行裁剪。我只是不知道如何知道堆栈中的变量。不是只有交出页码的可能性吗?还有:你如何使用这些运算符 eq/mod,我猜这是 postscript 特有的? eq 和 mod 是相等和模运算符。没有办法知道堆栈上有什么,你只需要知道,所以堆栈跟踪是一种特殊的 PostScript 技能(还有其他类似的语言)。没有一些编程就没有办法做你想做的事,而且由于它不是一个频繁的要求,Ghostscript 开发人员不可能为你添加它,所以你需要自己做。如果您发布您编写的代码而不是指向另一个答案,这可能会有所帮助。您一直小心使用 /PAGE pdfmark,而不是 /PAGES 不是吗? 谢谢肯斯。我在原始帖子中添加了我的“正在进行的工作”命令。 Ken,因为我是 *** 的新手,所以我不确定如何继续:我想将问题扩展到使用值数组以便能够将 pdf 的任何页面裁剪为单独的大小.我应该打开一个新问题还是编辑上述问题?

以上是关于如何使用 ghostscript 在多页 pdf 中裁剪第 3 和第 4 页的主要内容,如果未能解决你的问题,请参考以下文章

Ghostscript 多页 PDF 转 PNG

Ghostscript错误使用pdfwrite将多页PS转换为多页PDF

使用 Ghostscript 调整多页混合格式 PDF 的大小?

ImageMagick或GhostScript:将多页TIFF转换为多页PDF

Ghostscript:拆分多页 TIFF

在多页pdf的流程中附加一个块