如何使用 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错误使用pdfwrite将多页PS转换为多页PDF
使用 Ghostscript 调整多页混合格式 PDF 的大小?