Watermarking images with ImageMagick and BASH

Watermarking images with ImageMagick and BASH

Created:30 Oct 2017 21:11:08 , in  Host development

In this article I give a command line script for watermarking JPEG and PNG files with ImageMagick. Primary reason for me to write the script was the need of watermarking a large number of my own graphics files before posting them online as well as watermarking JPEGs and PNGs for various websites quick and effectively.


My script is called swww_watermark.sh and is written in BASH command language. It is designed for GNU Debian but should also work on other Unix-like operating systems. Under the bonnet it uses ImageMagick. ImageMagick is an open-source graphics editing suite available for both MS Windows and Unix-like operating systems. Make sure the suite is installed and patched properly (see a note on security below) on your system before running the script.

Watermarking BASH script

#!/usr/bin/env bash

# Script: swww_watermark.sh 
# Description: watermark JPEG and PNG images in a directory
# Author : Sylwester Wojnowski
# WWW : wojnowski.net.pl 

PICS_DIR='pics/' # default directory for images to watermark
PICS_EXT='jpg' # default extension of files to watermark
WMARK_PIC='watermark.jpg' # default watermarking image
GRAVITY='NorthWest' # NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast
GRAVITY_OPTS=(NorthWest North NorthEast West Center East SouthWest South SouthEast)
GEOMETRY_X=0 # ImageMagick geometry x coordinate value
GEOMETRY_Y=0 # ImageMagick geometry y coordinate value

ERROR_COMPOSITE_NOT_INST="ImageMagick composite command not available. Install ImageMagick and try again."
ERROR_NON_EXIST_DIR='ERROR: Given Image directory does not exist.'
ERROR_INCORRECT_EXT='ERROR: Unsupported image extension. This script support watermarking jpg and png files.'
ERROR_INCORRECT_X='ERROR: X co-ordinate for geometry option should be an integer.'
ERROR_GEOMETRY_Y='ERROR: Y co-ordinate for geometry option should be an integer.'
ERROR_NON_EXIST_WATERMARK_FILE='ERROR: Watermark file does not exist'

# === private === 

SCRIPTNAME=$(basename "$0")
read -r -d '' HP <<EOH
*** $SCRIPTNAME - watermark images in a directory using ImageMagick composite command.

* Synopsis: $SCRIPTNAME [-d directory] [-p extension] [ -g setting ] [ -x co-ordinate ] [ -y co-ordinate ] [ -w filename ] [ -h ] \n
      -d directory - directory with images to watermark, defaults to pics/
      -e extension - extension of image files to watermark, options are jpg,jpeg,png, defaults to jpg
      -g option - imagemagick gravity option, available options are:
         $GRAVITY_OPTS_STR ,defaults to NorthWest
      -x co-ordinate - geometry x co-ordinate, non-negative integer, defaults to 0
      -y co-ordinate - geometry y co-ordinate, non-negative integer, defaults to 0
      -w file - file to use for watermarking images
      -w file - file to use for watermarking images from directory given using -d option, defaults to watermark.jpg
      -h - help message
printf "\n%s\n" "$HP";

bail(){ echo "$1" >&2; help; exit 1; }
prereqs(){ [[ -z $(which composite) ]] && { bail "$ERROR_COMPOSITE_NOT_INST"; };}

  local OPTIND name
  while getopts "d:e:g:w:x:y:h" name; do
    case "$name" in
      d) # overwrite pics directory
      e) # overwrite file extension 
        [[ $OPTARG =~ $e_reg ]] && {
        } || { bail "$ERROR_INCORRECT_EXT"; }
      g) # overwrite gravity option
        for i in "${!GRAVITY_OPTS[@]}"; do
          [ "$OPTARG" == "${GRAVITY_OPTS[i]}" ] && {
        (( $gr_set == 0 )) && { bail "$ERROR_GRAVITY_SETTING"; }  
      x) #overwrite geometry x co-ordinate 
        [[ $OPTARG =~ $x_reg ]] && {
        } || { bail "$ERROR_INCORRECT_X"; }
      y) #overwrite geometry y co-ordinate
        [[ $OPTARG =~ $y_reg ]] && {
        } || { bail "$ERROR_INCORRECT_Y"; }
      w) # overwrite watermarking image name
       help; exit 1
  [ ! -d "$PICS_DIR" ] && { bail "$ERROR_NON_EXIST_DIR"; }
  [ ! -f "$WMARK_PIC" ] && { bail "$ERROR_NON_EXIST_WATERMARK_FILE"; }

  while read -r -d ''; do
    composite -gravity "$GRAVITY" \
     -geometry "+$GEOMETRY_X+$GEOMETRY_Y" "$WMARK_PIC" "$REPLY" "$REPLY"
  done < <(find "$PICS_DIR" -name "*.$PICS_EXT" -print0)  

validate_input "$@"

Configuration options

swww_watermark.sh has some configuration options. Among other things, they allow to specify a directory the script should look for images to watermark, a watermark file to use, type of files to watermark, or position of the watermark on the original image.

All the configuration options (each with a short description) are available after typing:

./swww_watermark.sh -h 

in your terminal window.

Use examples

Below are a couple of examples how the script can be used to watermark images.

As the first example, lets watermark all JPEG files in directory pics/ ( which lies in the same directory as swww_watermark.sh), with watermark file called watermark.jpg.


Watermarking all PNG files in directory ~/images with watermark /tmp/watermark.png can be done as follows:

./swww_watermark.sh -d ~images/ -e png -w watermark.png

By default, the watermark for each processed image will be placed in top-left corner of the image. Other locations for it can be given by specifying gravity (-g) and geometry(-x,-y) options (These options are described more thoroughly here).

./swww_watermark.sh -g Center

will watermark all JPEG images in pics/ by placing watermark.jpg in their centre.

./swww_watermark.sh -g Center -x 20 -y 40

will place watermark.jpg 20 pixels to the right from the centre and 40 pixels to bottom from the centre of the image being watermarked.

Both, x and y options can also accept negative values, in such a case a shift will take place to the left and top by the number of pixels specified respectively.

A note on security

In year 2016 a number of vulnerabilities have been discovered in the code ImageMagick graphics suite relies upon. Details on the issues and how to mitigate it can be found here and here. You should make sure your installation of ImageMagick is properly patched and configured before trying to manipulate images from distrusted sources, like user downloads, with its commands.

Final thoughts

Watermarking images is a frequent requirement these days. Quite a few high-level programming languages rely upon ImageMagick bindings to perform the task. BASH, a command language, does not depend on any extra code like that. Instead, it enjoys a sort of more direct access to the wealth of commands ImageMagick suite ( and many other CLI programs ) provide. I like this direct link, it simplifies considerably writing scripts like the one presented in this article.

I hope the article has been an interesting read, and the code in it will prove useful to you.

This post was updated on 31 Oct 2017 00:00:40

Tags:  BASH ,  image ,  ImageMagick 

Author, Copyright and citation


Sylwester Wojnowski

Author of the this article - Sylwester Wojnowski - is a sWWW web developer. He has been writing computer code for the websites and web applications since 1998.


©Copyright, 2022 Sylwester Wojnowski. This article may not be reproduced or published as a whole or in parts without permission from the author. If you share it, please give author credit and do not remove embedded links.

Computer code, if present in the article, is excluded from the above and licensed under GPLv3.


Cite this article as:

Wojnowski, Sylwester. "Watermarking images with ImageMagick and BASH." From sWWW - Code For The Web . https://wojnowski.net.pl//main/index/watermarking-images-with-imagemagick-and-bash

Add Comment

Allowed BB Code - style tags: [b][/b], [i][/i], [code=text][/code],[code=javascript][/code],[code=php][/code],[code=bash][/code],[code=css][/code],[code=html][/code]

I constent to processing my data given through this form for purposes of a reply by the administrator of this website.

Recent Comments

Nobody has commented on this post yet. Be first!