debian-pdfrw/examples/fancy_watermark.py

106 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python
'''
Enhanced example of watermarking using form xobjects (pdfrw).
usage: fancy_watermark.py [-u] my.pdf single_page.pdf
Creates watermark.my.pdf, with every page overlaid with
first page from single_page.pdf. If -u is selected, watermark
will be placed underneath page (painted first).
The stock watermark.py program assumes all pages are the same
size. This example deals with pages of differing sizes in order
to show some concepts of positioning and scaling.
This version applies the watermark such that the upper right
corner of the watermark is at the upper right corner of the
document page for odd pages, and at the upper left corner
of the document page for even pages, for each page of the
document.
It also rescales the size of the watermark if the watermark
is too wide for the page.
These scaling and positioning adjustments can easily
be customized for any particular application.
To handle documents with different page sizes, a cache is
maintained of a modified intermediate watermark object
for each page size.
'''
import sys
import os
from pdfrw import PdfReader, PdfWriter, PageMerge
# Get all the filenames
argv = sys.argv[1:]
underneath = '-u' in argv
if underneath:
del argv[argv.index('-u')]
inpfn, wmarkfn = argv
outfn = 'watermark.' + os.path.basename(inpfn)
# Open both the source files
wmark_trailer = PdfReader(wmarkfn)
trailer = PdfReader(inpfn)
# Handle different sized pages in same document with
# a memoization cache, so we don't create more watermark
# objects than we need to (typically only one per document).
wmark_page = wmark_trailer.pages[0]
wmark_cache = {}
# Process every page
for pagenum, page in enumerate(trailer.pages, 1):
# Get the media box of the page, and see
# if we have a matching watermark in the cache
mbox = tuple(float(x) for x in page.MediaBox)
odd = pagenum & 1
key = mbox, odd
wmark = wmark_cache.get(key)
if wmark is None:
# Create and cache a new watermark object.
wmark = wmark_cache[key] = PageMerge().add(wmark_page)[0]
# The math is more complete than it probably needs to be,
# because the origin of all pages is almost always (0, 0).
# Nonetheless, we illustrate all the values and their names.
page_x, page_y, page_x1, page_y1 = mbox
page_w = page_x1 - page_x
page_h = page_y1 - page_y # For illustration, not used
# Scale the watermark if it is too wide for the page
# (Could do the same for height instead if needed)
if wmark.w > page_w:
wmark.scale(1.0 * page_w / wmark.w)
# Always put watermark at the top of the page
# (but see horizontal positioning for other ideas)
wmark.y += page_y1 - wmark.h
# For odd pages, put it at the left of the page,
# and for even pages, put it on the right of the page.
if odd:
wmark.x = page_x
else:
wmark.x += page_x1 - wmark.w
# Optimize the case where the watermark is same width
# as page.
if page_w == wmark.w:
wmark_cache[mbox, not odd] = wmark
# Add the watermark to the page
PageMerge(page).add(wmark, prepend=underneath).render()
# Write out the destination file
PdfWriter(outfn, trailer=trailer).write()