【问题标题】:Is it possible in Ghostscript to add watermark to every page in PDF是否可以在 Ghostscript 中为 PDF 的每一页添加水印
【发布时间】:2012-09-03 06:38:03
【问题描述】:

我使用 ghostscript 转换 PDF -> many JPEGmany JPEG -> many PDF。我需要在每个转换后的 JPEG (PDF) 页面上添加水印文本。是否可以只使用 Ghostscript 和 PostScript?

我找到的唯一方法:

gswin32c -q -sDEVICE=pdfwrite -dBATCH -dNOPAUSE -sOutputFile=output.pdf watermark.ps input.pdf

但这会在output.pdf的第一个单独页面上插入watermark.ps水印。

我可以直接在输出 PDF 页面上执行此操作吗?

我可以直接在输出 JPEG 页面上执行此操作吗?

<<
   /BeginPage
   { gsave
       /Helvetica_Bold 120 selectfont
       .85 setgray 130 70 moveto 50 rotate (Sample) show
     grestore
   } bind
>> setpagedevice

如果我使用/EndPage 而不是/BeginPage - 它说setpagedevice 不适用...

如何为/EndPage 重新制作这个脚本?

【问题讨论】:

    标签: pdf jpeg ghostscript watermark postscript


    【解决方案1】:

    评论太大了,所以我添加了一个新答案。 EndPage 过程(请参阅 PostScript 语言参考手册的第 441 页)在堆栈上采用两个附加参数、到目前为止发出的页面计数和原因代码。

    您可以使用页数来做一些有趣的事情,例如双面打印,或者只标记偶数页或其他任何东西,但我假设在这种情况下您不想要它,所以您只需将其从堆栈中“弹出”即可。

    原因代码告诉你为什么页面被发出,你可能不在乎,所以你只是弹出值。

    最后,EndPage 必须向解释器返回一个布尔值,说明是否传输页面(这允许您做其他有趣的事情,比如只打印前 10 页等等)。

    因此,您首先需要删除两个值,执行您的代码并返回一个布尔值。很简单:

    <<
       /EndPage
       { pop pop %% *BEFORE* gsave as that puts a gsave object on the stack
         gsave
         /Helvetica_Bold 120 selectfont
         .85 setgray 130 70 moveto 50 rotate (Sample) show
         grestore
         true %% transmit the page, set to false to not transmit the page
       } bind
    >> setpagedevice
    

    【讨论】:

    • 它几乎是正确的,除了每个真正的水印页面之外,它还添加了带水印的空白页面,并且输出 PDF 有两倍多的页面。
    • 可能是“原因”代码是问题所在。试试这个:/EndPage {exch pop 2 lt {gsave...grestore true}{false} ifelse} 绑定
    • 我这样做了:> setpagedevice 并导致错误:Error: /typecheck in --.endpage-- Operand stack: --nostringval-- 2 2 2
    • 哦,我找到了。我使用if 而不是lt。有用。太好了!
    【解决方案2】:

    接受的答案是为我插入页面。除了水印,页面都是空白的。如果您遇到这种情况,请尝试在此处添加 2eq 位

    <<
       /EndPage
       {
         2 eq { pop false }
         {
             gsave      
             /Helvetica_Bold 120 selectfont
             .85 setgray 130 70 moveto 50 rotate (Sample) show
             grestore
             true
         } ifelse
       } bind
    >> setpagedevice
    

    我发现以下网站为我指明了正确的方向

    http://habjan.blogspot.com/2013/10/how-to-programmatically-add-watermark.html

    这里是上述文件保存为 watermark.ps 和 gswin32c 引用 ghostscript exe 的调用语法

    gswin32c -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=watermarked.pdf watermark.ps original.pdf
    

    【讨论】:

    • 请注意,这会产生“印章”(前景文本),而不是水印(背景文本)。将/EndPage替换为/BeginPage获取水印
    【解决方案3】:

    我不知道您所说的“直接”是什么意思。正如您所发现的,让 PostScript 解释器在每页的基础上执行多种操作是可能的。 PostScript 毕竟是一种编程语言。

    我建议从页面设备字典中的 /BeginPage 和/或 /EndPage 过程开始。这些允许您在每一页的开头或结尾执行任意 PostScript。

    如果您定义了 /BeginPage 过程,那么它将在输入程序的任何标记操作之前执行,如果您定义了 /EndPage,那么它将在 之后执行来自输入程序的标记操作(逐页(。

    这允许您将自己的标记置于程序标记的“下方”或“上方”。

    【讨论】:

    • 我已经用代码示例更新了问题。可以看看吗?
    猜你喜欢
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多