如何使用 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
这不是世界上最简洁的解决方案,但对我有用。
我想在多页 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
这不是世界上最简洁的解决方案,但对我有用。