Watermarking Images--from the Command Line

Now let's have a quick test:

$ sh bigimages.sh
File screenshot-6.png (1800x490) has file size 9.639MB

It's definitely more informative than just doing an ls -l and particularly so if you were to put this in an automatic email report for hosting clients!

Why? Because lots of people who aren't tech-savvy upload images directly from digital cameras—images that can be enormous. They resize the displayed image in their blog posts, but the original files are way larger than necessary, slowing down their sites unnecessarily.

Before moving on, let me make a few comments. First, notice the size test with find: -size +8M. find has a weird view of numbers and comparisons, and the test -size 8M would match only files that are exactly 8MB in size—not useful. Without the "M" suffix, the test would be comparing to 512-byte blocks, so +8 would match a lot of files (because eight 512-byte blocks is only 4K, and that's tiny for an image file). find also knows "K" for kilobytes, "G" for gigabytes, "T" for terabytes and, yes, "P" for petabytes.

The second observation to make is the use of quotes with the echo statement. Try it. Without quotes, the shell would complain about the use of parentheses, and with single quotes, it would show the variable names, not expand them. It's a good real-world reminder of the subtle, but important quote nuances in the shell!

Add a Watermark

One of the most popular uses of ImageMagick isn't to identify image dimensions but to add watermarks. You've seen watermarks on images all over the web. Sometimes it's a little copyright notice, a URL or even a tiny graphical bug that identifies the source or ownership of the image.

Nice effect, but how do you do it? Use the convert command. In fact, if you want to just add a text overlay on the bottom of an image, the command is simple:

convert $source label:'LinuxJournal.com'-append $output

The default isn't very glamorous, however, so you'll inevitably want to customize it a bit. To make the font a bit larger, use -pointsize, and to move the watermark text to be in the lower right instead of its default position, use -gravity.

This is a bit more sophisticated and shows some of the weirdness of ImageMagick:

convert $source -pointsize 80 -gravity east \
    label:'LinuxJournal.com' -append $output

This easily can be poured into a script, of course, and either you can have the output images in a different directory or you can rewrite the source filename appropriately. My favorite way to accomplish the latter is this:

predot=$(echo $name | rev | cut -d. -f2- | rev)
postdot=$(echo $name | rev | cut -d. -f1 | rev)
newname=$(echo ${predot}-wm.$postdot)

Since there's no "last field" option in cut, the way to grab just the filename suffix, even if the base filename contains dots, is to reverse the name, grab the first field, then reverse it again. This way, you can take a filename like "red.rose.png" and rewrite it as "red.rose-wm.png" to denote the version that has the watermark added.

But, what if you have a small graphic bug you want to overlay on the lower left corner of the image instead?


Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.