First, get the dimensions of the base and watermark images:
#!/bin/bash
infile="$1"
outfile="$2"
wmfile="watermark.png"
basew=`identify -format '%w' "$infile"`
baseh=`identify -format '%h' "$infile"`
wmw=`identify -format '%w' "$wmfile"`
wmh=`identify -format '%h' "$wmfile"`
Then, calculate how many complete tiles we can fit over the base image:
tilew=$(($basew / $wmw * $wmw))
tileh=$(($baseh / $wmh * $wmh))
This uses integer arithmetic, so the multiply operation doesn't counteract the divide. Let's take an example. If the base image is 100x100 and the tile image 34x34, this will yield 68x68, since you can't quite fit a third tile in on either axis.
Note that we're using a Bash feature here to do arithmetic within the shell script proper. If you have to do this in another shell, you can call out to bc
or dc
to do the calculation externally.
Now that we know how large we can make it, create a tiled temporary version of the watermark image, centered within a frame equal to the size of the base image:
wmtemp=`mktemp /tmp/wm-XXXXXX.png`
convert -background 'rgba(0,0,0,0)' -size "$tilew"x"$tileh" \
tile:"$wmfile" -gravity center -extent "$basew"x"$baseh" \
png32:$wmtemp
Notice that this forces the watermark image to RGBA format if it wasn't already. Also, it's important that the -background 'rgba(0,0,0,0)'
directive be before the input image, so it doesn't do the tiling operation over the default white background.
The real trick here, though, is that we're using different values for the -size
and -extent
directives. We're building up a potentially smaller tiled image, then padding it out if needed to match the size of the base image. If the tile image size divides evenly into the base image size, that's fine, it simply won't have to add any extra padding to center the tile set.
Finally, lay the temporary tiled watermark over the original image:
composite "$wmtemp" "$infile" "$outfile"
rm "$wmtemp"
convert
to add half the difference betweenbasew
andtilew
to the tile x-axis offset and similar for the y-axis with the heights. If so, you'd save some I/O and compression time. Anyway, you're going to accept the answer now and stop stringing me along, right? :) – Warren Young Aug 18 '12 at 08:01