【问题标题】:PDF crop even-odd pages with PHP + GhostScriptPDF 使用 PHP + GhostScript 裁剪奇偶页
【发布时间】:2015-08-05 11:48:38
【问题描述】:

我正在例行裁剪 PDF 并将它们导入 PDF 模板。我正在使用 GhostScript,通过 PHP 脚本中的 exec() 和 FPDI 调用。全部运行在服务器端。

到目前为止,我可以使用this post(设置CropBox)中说明的过程使用 GhostScript 裁剪 pdf 文档。

下一步是对文档的偶数页和奇数页进行不同的裁剪。所以我尝试了SuperUser站点this other post中解释的方法,将自定义PostScript代码传递给GhostScript的-c参数:

-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {28 0 translate} {} ifelse } bind  >> setpagedevice"

此方法将奇数页移动 28 pt,对偶数页不执行任何操作。因此,我尝试修改它,传递 CropBox(es)(在 sprintf 句子中将 %s 占位符替换为适当的坐标):

-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {[/CropBox [%s %s %s %s]} {[/CropBox [%s %s %s %s]} 
ifelse } bind  >> setpagedevice"

这是对 4 页 pdf 文件执行的完整命令:

"C:\Program Files (x86)\gs\gs9.07\bin\gswin32c.exe" -sDEVICE=pdfwrite 
-o C:\inetpub\wwwroot\ledrail\tmp\output.pdf 
-c "<< /CurrPageNum 1 def /Install { /CurrPageNum CurrPageNum 1 add def 
CurrPageNum 2 mod 1 eq {[/CropBox [119.04 168.336 505.92 715.428]}
{[/CropBox [59.52 84.168 505.92 715.428]} ifelse } bind >> setpagedevice"
-f C:\inetpub\wwwroot\ledrail\documentacio\pdf\documentacio_15.pdf

显然,我收到一个错误,因为[/CropBox... 不是有效的 PS 代码。

Error: /typecheck in --.postinstall--

编辑澄清:

所以,我的问题是:我如何将 相当于 两个 CropBox(es)(用于奇数页和偶数页)传递给上面显示的 PostScript 代码?或者,还有另一种方法可以从命令行使用 GhostScript 实现此目的?

显然,我知道 CropBox 不是 PostScript 的有效代码,但有什么替代方案?

【问题讨论】:

    标签: php pdf ghostscript postscript


    【解决方案1】:

    您不能在 PostScript 中设置“CropBox”,因为 CropBox 不是 PostScript 语言的一部分,它是 PDF 特有的。

    正如您引用的第一篇文章所说,您需要发送带有 /CropBox 的 /PAGE pdfmark。您没有设置 /Install。

    【讨论】:

    • 我忽略了我的问题。当然,当我说我可以建立一个 CropBox 时,我使用的是:"C:\Program Files (x86)\gs\gs9.07\bin\gswin32c.exe" -sDEVICE=pdfwrite -o C:\inetpub\wwwroot\ledrail\tmp\output.pdf -c "[/CropBox[89.28 126.252 505.92 715.428] /PAGES pdfmark" -f C:\inetpub\wwwroot\ledrail\documentacio\pdf\documentacio_15.pdf
    • 您需要 /PAGE pdfmark 而不是 /PAGES pdfmark。 PAGES 影响所有
    • 谢谢,KenS。那么,除了-f-l 参数之外,还有其他方法-使用GhostScript-确定页面范围-确定连续页面吗?在我上一条评论的命令中,哪个页面将适用/PAGE
    • -f 只是 PostScript 输入的结束(在命令行上)。你需要结合你的两种方法。您需要一个 /EndPage 过程(确实被传递给 setpagedevice)并且该过程需要调用 pdfmark。 EndPage 过程在堆栈中使用 2 个值调用,其中之一是到目前为止发出的页面数。因此,您可以使用它来确定为 pdfmark 设置哪些值。在此处查看以前的答案:stackoverflow.com/questions/26985557/…
    • -c "&lt;&lt;/EndPage {0 eq {2 mod 0 eq {[/CropBox [%s %s %s %s] /PAGE pdfmark true} {[/CropBox [%s %s %s %s] /PAGE pdfmark true} ifelse}{false}ifelse}&gt;&gt; setpagedevice" 好吧,那终于成功了!!!如果我正确理解逻辑(借助 PLRM ed.3),外部ifelse 测试(0 eq)showpage 执行;内部ifelse (2 mod 0 eq) 测试奇数/偶数页,在调用setpagedevice 时提供相应的CropBox。
    【解决方案2】:

    GhostScript 可以处理 PostScript 文件和在命令行通过 -c 参数传递的 PostScript 命令。因此,为了实现不平凡的事情,您至少应该了解该语言的基础知识。

    从以下来源获取相关文档:PostScript Language Reference Manual, 3rd ed.PostScript Language Tutorial and Cookbook,如果您在生活中没有见过 PostScript(就像我的情况一样)。

    KenS 指点我:

    您需要一个 /EndPage 过程(确实会传递给 setpagedevice) 并且该程序需要调用pdfmark。

    文档声明 EndPage

    在每页末尾执行的过程。在调用之前 过程中,解释器将两个整数压入操作数堆栈——一个 此设备之前执行的显示页面计数和原因 指示进行此调用的情况的代码:

    0 - 在展示页面或(LanguageLevel 3)复制页面期间

    1 - 在复制页面期间(仅限语言级别 2)

    2 - 设备停用时

    程序必须 返回一个布尔值,指定是否传输页面图像 到物理输出设备。

    所以,这段代码(来自 KenS 的previous answer

    <</EndPage {0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true}{false}ifelse}>> setpagedevice
    

    为当前页面传递一个CropBox - 指定坐标 - 每次EndPage 以原因0(显示页面)被调用并返回true。否则,什么都不做并返回 false。这个原因码是操作数栈中的第一项,在操作0 eq {true block}{false block} ifelse(等于0?)中被“消耗”后,栈中就没有了。

    因此,堆栈中的下一个值是处理的页数。我们在上面显示的true 部分代码中使用另一个ifelse 扩展代码:

    {2 mod 0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true} 
    {[/CropBox [50 0 612 792] /PAGE pdfmark true} ifelse}
    

    这会在当前页面(堆栈顶部)和 2 之间执行模数,然后测试是否等于 0(即测试奇数/偶数页)。如果 even (modulus = 0) 通过第一个 CropBox,否则通过第二个,并且在两种情况下都返回 true。

    那么,完整的 PostScript 代码:

    "<</EndPage {0 eq {2 mod 0 eq {[/CropBox [0 0 612 792] /PAGE pdfmark true}
    {[/CropBox [50 0 612 792] /PAGE pdfmark true} ifelse}{false}ifelse}>> setpagedevice"
    

    当作为 -c 参数传入 GhostScript 时,允许我们以不同的方式裁剪 PDF 文档的偶数页和奇数页,即,如果我们想抑制用于绑定原始文件的额外空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-05
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多