How to create a script on MacOS automator to Watermark each file in a folder with a different set of watermarks?

I am trying to create a script to watermark a group a PDF files in a folder, each PDF has to have a unique watermark.


All the PDFs are in one folder, all the watermarks are in .png located in another folder.

I currently have watermark script which I found on Apple Forums, but this was made to watermark all files with one watermark only.


What I need is a way to watermark each PDF file with it's own different watermark (there are 400 pdfs and 400 different watermarks)


Please help if you can, Thank You.

MacBook Pro 15″, macOS 10.12

Posted on Nov 28, 2020 9:11 AM

Reply
Question marked as Top-ranking reply

Posted on Nov 28, 2020 7:01 PM

It's been so long I forgot that tool.py was in the resource package.

And yes, I stopped using that tool.py as at some point the Watermark Automator Action started working again.


So, knowing that, as long as the OP has named the Watermark with the same name as the PDF, and they all have the same format, (and not a mix of jpeg's and png's - i.e. File_01.pdf and File_02.png), then all than needs to be done is to add one line to the loop I posted above. The Watermarked PDF will be output to the Desktop.


I tested this with only a few files:


#!/bin/bash

for f in $HOME/Documents/*					# <-- Point to dir with PDF's
do
	if [ "${f##*.}" = "pdf" ] ; then
		basename="${f##*/}"
		name="${basename%.*}" 
		pngfile="$HOME/Desktop/$name.png"	# <-- Point to dir with Watermarks
		if [ -f "$pngfile" ] ; then
			/System/Library/Automator/Watermark\ PDF\ Documents.action/Contents/Resources/tool.py --under --xOffset 15 --yOffset 55 --angle 0 --scale 0.75 --opacity 0.5 --input "$f" --output "$HOME/Desktop/$name.pdf" "$pngfile"
		else
			echo PNG file not found for "$f"
		fi
	fi
done




Similar questions

27 replies

Nov 28, 2020 6:13 PM in response to Tony T1

From Mojave thru Big Sur, Apple replaced the tool.py with a compiled binary in the System/Library/Automator/Watermark PDF Documents.action. Though this is also true with High Sierra 10.13.6, Apple left the tool.py script in that package folder's Resources directory. I just ran it on my M1 mini on Big Sur and it works.


The OP has not stated if the image name matches the PDF name, or not. Simpler if it does, as one would then have to embed the tool.py in a script loop that can manage to get the PDF and image name supplied to the Python script. The fly in the oitment is that a new watermarked PDF has to be written out, as in-place watermarks are not going to happen.

Nov 29, 2020 4:10 AM in response to Tony T1

No file is generated in the Desktop.


I'm a Civil Engineer and have been at this for a long time now. I saw your posts from previous years and they were very helpful. Thank you for your response.


I used name use the same names for the .PDF files and .png files.


I tried the script you sent. Automator shows no error, but no file is generated in the Desktop.

I changed the PDF and PNG directories. Also changed the tool.py directory because I'm using MacOS Mojave, and checked that –– /System/Library/Automator/Watermark\ PDF\ Documents.action/Contents/Resources/tool.py –– does not contain tool.py


The tool.py code that I have is https://pastebin.com/e5xjS3en


Nov 29, 2020 5:15 AM in response to VikingOSX

Here's the tool.py script from my watermark action resource folder (High Sierra)


#!/usr/bin/python

# Watermark each page in a PDF document

#

# From /System/Library/Automator/Watermark PDF Documents.action/Contents/Resources/tool.py


import sys

import getopt

import math

import shutil

import CoreGraphics

from Quartz.ImageIO import *


def drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity):

if image:

imageWidth = CGImageGetWidth(image)

imageHeight = CGImageGetHeight(image)

imageBox = CGRectMake(0, 0, imageWidth, imageHeight)

CGContextSaveGState(ctx)

CGContextSetAlpha(ctx, opacity)

CGContextTranslateCTM(ctx, xOffset, yOffset)

CGContextScaleCTM(ctx, scale, scale)

CGContextTranslateCTM(ctx, imageWidth / 2, imageHeight / 2)

CGContextRotateCTM(ctx, angle * math.pi / 180)

CGContextTranslateCTM(ctx, -imageWidth / 2, -imageHeight / 2)

CGContextDrawImage(ctx, imageBox, image)

CGContextRestoreGState(ctx)


def createImage(imagePath):

image = None

provider = CGDataProviderCreateWithFilename(imagePath)

if provider:

imageSrc = CGImageSourceCreateWithDataProvider(provider, None)

if imageSrc:

image = CGImageSourceCreateImageAtIndex(imageSrc, 0, None)

if not image:

print "Cannot import the image from file %s" % imagePath

return image


def watermark(inputFile, watermarkFiles, outputFile, under, xOffset, yOffset, angle, scale, opacity, verbose):

images = map(createImage, watermarkFiles)

ctx = CGPDFContextCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, outputFile, len(outputFile), False), None, None)

if ctx:

pdf = CGPDFDocumentCreateWithURL(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, inputFile, len(inputFile), False))

if pdf:

for i in range(1, CGPDFDocumentGetNumberOfPages(pdf) + 1):

image = images[i % len(images) - 1]

page = CGPDFDocumentGetPage(pdf, i)

if page:

mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox)

if CGRectIsEmpty(mediaBox):

mediaBox = None

CGContextBeginPage(ctx, mediaBox)

if under:

drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity)

CGContextDrawPDFPage(ctx, page)

if not under:

drawWatermark(ctx, image, xOffset, yOffset, angle, scale, opacity)

CGContextEndPage(ctx)

del pdf

CGPDFContextClose(ctx)

del ctx


def main(argv):


verbose = False

readFilename = None

writeFilename = None

under = False

xOffset = 0

yOffset = 0

angle = 0

opacity = 1.0

scale = 1.0

# Parse the command line options

try:

options, args = getopt.getopt(argv, "vutx:y:a:p:s:i:o:", ["verbose", "under", "over", "xOffset=", "yOffset=", "angle=", "opacity=", "scale=", "input=", "output=", ])

except getopt.GetoptError:

usage()

sys.exit(2)

for option, arg in options:

print option, arg

if option in ("-i", "--input") :

if verbose:

print "Reading pages from %s." % (arg)

readFilename = arg


elif option in ("-o", "--output") :

if verbose:

print "Setting %s as the output." % (arg)

writeFilename = arg


elif option in ("-v", "--verbose") :

print "Verbose mode enabled."

verbose = True


elif option in ("-u", "--under"):

print "watermark under PDF"

under = True


elif option in ("-t", "--over"):

print "watermark over PDF"

under = False

elif option in ("-x", "--xOffset"):

xOffset = float(arg)

elif option in ("-y", "--yOffset"):

yOffset = float(arg)

elif option in ("-a", "--angle"):

angle = -float(arg)


elif option in ("-s", "--scale"):

scale = float(arg)

elif option in ("-p", "--opacity"):

opacity = float(arg)

else:

print "Unknown argument: %s" % (option)


if (len(args) > 0):

watermark(readFilename, args, writeFilename, under, xOffset, yOffset, angle, scale, opacity, verbose);

else:

shutil.copyfile(readFilename, writeFilename);

def usage():

print "Usage: watermark --input <file> --output <file> <watermark files>..."

if __name__ == "__main__":

print sys.argv

main(sys.argv[1:])

Nov 29, 2020 7:40 AM in response to Tony T1

Thank you.


Downloaded the file (tool.py) on the link you sent on Dropbox. Now I have to make it executable on terminal (chmod u+x)?


And then, how do I run this script? Should I run it on Automator? ⬇️


#!/bin/bash

for f in $/Users/lauromota/Desktop/PDF*					# <-- Point to dir with PDF's
do
	if [ "${f##*.}" = "pdf" -o  "${f##*.}" = "PDF" ] ; then
		basename="${f##*/}"
		name="${basename%.*}" 
		pngfile="$Users/lauromota/Desktop/QRtest/$name.png"	# <-- Point to dir with Watermarks
		if [ -f "$pngfile" ] ; then
			/Users/lauromota/Desktop/Script/tool.py --over --xOffset 58 --yOffset 58 --angle 0 --scale 0.11 --opacity 1 --input "$f" --output "$Users/lauromota/Desktop/$name.pdf" "$pngfile"
		else
			pngfile="$Users/lauromota/Desktop/QRtest/$name.PNG"    # <-- Point to dir with Watermarks
			if [ -f "$pngfile" ] ; then
				/Users/lauromota/Desktop/Script/tool.py --under --xOffset 15 --yOffset 55 --angle 0 --scale 0.75 --opacity 0.5 --input "$f" --output "$Users/lauromota/Desktop/$name.pdf" "$pngfile"
				else
					echo PNG file not found for "$f"
			fi
		fi
	fi
done


Did I write the directories correctly?

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

How to create a script on MacOS automator to Watermark each file in a folder with a different set of watermarks?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.