Is it possible in Ghostscript to add watermark to every page in PDF
Asked Answered
C

4

11

I convert PDF -> many JPEG and many JPEG -> many PDF using ghostscript. I need to add watermark text on every converted JPEG (PDF) page. Is it possible using only Ghostscript and PostScript?

The only way I found:

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

But this will insert watermark.ps watermark on first separate page in output.pdf.

Can I do this on output PDF pages directly?

Can I do this on output JPEG pages directly?

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

If I use /EndPage instead of /BeginPage - it says setpagedevice is not applicable...

How to remake this script for /EndPage?

Coprophagous answered 3/9, 2012 at 6:38 Comment(0)
C
9

Bit too big for a comment, so I've added a new answer. The EndPage procedure (see page 441 of the PostScript Language Reference Manual) takes two additional parameters on the stack, a count of pages emitted so far, and a reason code.

You can use the count of pages to do interesting things like duplexing, or only marking even pages or whatever, but I assume in this case you don't want it, so you just 'pop' it from the stack.

The reason code tells you why the page is being emitted, again you probably don't care so you just pop the value.

Finally the EndPage must return a boolean value to the interpreter saying whether or not to transmit the page (this allows you to do other interesting things, like only printing the first 10 pages and so on).

So you need to initially remove two values, execute your code and return a boolean. Pretty trivial:

<<
   /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
Countersign answered 26/9, 2012 at 7:26 Comment(4)
It almost correct, excluding for every real watermarked page it also adds empty page with watermark and output PDF have twice pages more.Coprophagous
Possibly the 'reason' code is the problem. Try this: /EndPage {exch pop 2 lt {gsave...grestore true}{false} ifelse} bindCountersign
I did this: << /EndPage { exch pop 2 if { gsave /Helvetica_Bold 120 selectfont .85 setgray 130 70 moveto 50 rotate (Sample) show grestore true } {false} ifelse } bind >> setpagedevice and it cause error: Error: /typecheck in --.endpage-- Operand stack: --nostringval-- 2 2 2Coprophagous
Oh, i found it. I used if instead of lt. It works. Great!Coprophagous
S
6

The accepted answer was inserting pages for me. The pages were blank aside from the watermark. If you run into this try adding the 2eq bit here

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

I found the following site that pointed me in the correct direction

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

Here's the calling syntax where the above file is saved as watermark.ps and gswin32c references the ghostscript exe

gswin32c -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=watermarked.pdf watermark.ps original.pdf
Selfsown answered 7/8, 2014 at 16:25 Comment(1)
Please note that this results in a "stamp" (text on foreground), not a watermark (text on background). Replace /EndPage with /BeginPage to obtain a watermarkVortex
C
1

I don't know what you mean by 'directly'. Its possible, as you have found, to have a PostScript interpreter do many kinds of things on a per-page basis. PostScript is a programming language after all.

I would suggest that the /BeginPage and/or /EndPage procedures in the page device dictionary would be the place to start. These allow you to execute arbitrary PostScript at the start or end of every page.

If you define a /BeginPage procedure then it will be executed before any marking operations from the input program, if you define a /EndPage then it will be executed after the marking operations from the input program (on a page by page basis(.

This allows you to have your own marks lie 'under' or 'over' the marks from the program.

Countersign answered 3/9, 2012 at 7:11 Comment(1)
i've updated question with code example. Can you take a look?Coprophagous
H
0

I've faced the problem of creating a transparent text watermark on each page of the pdf-file.

Some info about transparency in Ghostscript. As the doc says - by default it doesn't support. You can read more information about it here. The doc says that you have to build the Ghostscript with "transpar" option. I didn't do that, but it works for me.

My solution.

0)Ghostscript version: 9.53.3

1)Create mark.ps file:

<<
   /EndPage
   {
     2 eq { pop false }
     {
        gsave
        /Helvetica 45 selectfont
        25 rotate
        .85 setgray
        .8 .setfillconstantalpha
        130 10 moveto (My Super Watermark) show
        240 90 moveto (My Super Watermark) show
        grestore
        true
     } ifelse
   } bind
>> setpagedevice

2)Run ghostscript:

gs -dBATCH -dNOPAUSE -dQUIET -dALLOWPSTRANSPARENCY -dAutoRotatePages=/None -sDEVICE=pdfwrite -sOutputFile=my_result.pdf mark.ps my_source.pdf

3)The key options for transparency are:

.8 .setfillconstantalpha in mark.ps file, and -dALLOWPSTRANSPARENCY in gs command.

4)If you need to slice pdf-file into images. You can get much less size of image if you'll make png-images, not jpeg. After my tests, the best way:

gs -dBATCH -dNOPAUSE -dQUIET -sDEVICE=pnggray -r72 -o /tmp/result_images/mm-%d.png my_source.pdf

In addition.

Full Ghostscript doc here.

Holograph answered 9/7, 2023 at 16:50 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.