Note: This script runs only on Gnu/Linux platform as of now. Volunteer contribution is welcome to make it work on other platforms.

When I started publishing my photos to blog, I was faced with a bulk watermarking photos issue. Its just a one line command in Linux, to watermark photos but then my requirement grew more than that so I wrote a bash shell script to achieve my goal.

You can visit the project at https://gitlab.com/abhijitnavale/watermark_photos . Here is what my bash shell script does:

  1. Rotate images automatically using their EXIF information
  2. Adds Watermark to all photos in source folder
  3. Removes EXIF information from all those photos
  4. Changes the scale of images.

Since I do not need last scaling option on regular basis, I have not completed my script to properly handle this option. You have to manually uncomment the scaling line from source bash script file. Dimensions for scaling are in the format of WidthxHeight.

You are welcome to improve this script to handle this option along with making it UNIX standards complaint.

For your logo, it is recommended to create a watermark logo image in .png format. Please edit the “LOGO_PATH” variable in the script and point it to your logo file using full absolute path.

This script uses Imagemagick and ExifTool to process photos. Imagemagick does the scaling, applying watermark and rotating part. ExifTool removes the EXIF information from photos.

From EXIF wikipedia page https://en.wikipedia.org/wiki/Exif , Exchangeable image file format (officially Exif, according to JEIDA/JEITA/CIPA specifications) is a standard that specifies the formats for images, sound, and ancillary tags used by digital cameras (including smartphones), scanners and other systems handling image and sound files recorded by digital cameras.

We remove EXIF for different reasons including privacy.

To use the script:

  1. mark the script executable
  2. Run
    ./watermark.sh <full_absolute_path_of_source_folder>[optional_logo_position]

Running just ./watermark.sh without any arguments will give you list of all logo gravity positions along with error.

Checkout the README file at that project to know more details. Here is the complete source code of that script:

# Copyright (c) 2017 Abhijit Navale
#
# MIT License
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#!/bin/bash
#
# https://www.imagemagick.org/script/command-line-options.php#gravity
# Available Gravity Types:
#
#   NorthWest,
#   North,
#   NorthEast,
#   West,
#   Center,
#   East,
#   SouthWest,
#   South,
#   SouthEast<span 				data-mce-type="bookmark" 				id="mce_SELREST_start" 				data-mce-style="overflow:hidden;line-height:0" 				style="overflow:hidden;line-height:0" 			></span>
#
# ----------
# Configure Variables
# ----------
#
WATERMARK_DIR="WaterMarked_Photos"

# Use Full Absolute Path
LOGO_PATH="/home/<username>/Pictures/watermark.png"

readonly GRAVITY_TYPES=(NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast)
readonly PHOTO_TYPES=(jpg jpeg jfif png exif tiff gif bmp)

if [ -z "$1" ]
then
    echo
    echo "ERROR!"
    echo
    echo "Source Photo Directory Missing."
    echo "Syntax: "
    echo "./watermark.sh <source_directory_with_absolute_path> [optional_logo_position]"
    echo
    echo "Available Logo Positions are:"
    echo "NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast"
    echo
    echo "EXITING."
    exit 1
fi

if [ ! -f "$LOGO_PATH" ]
then
    echo
    echo "ERROR!! Watermark Logo file not found at $LOGO_PATH"
    echo
    echo "EXITING"
    exit 1
fi

# Default Logo Position. Second argument to script overrides this.
LOGO_POSITION="SouthWest"

# use logo position provided by user argument
if [ ! -z "$2" ]
then
    if [[ " ${GRAVITY_TYPES[@]} " =~ " ${2} " ]]
    then
        echo
        echo "Changing Logo position to $2"
        LOGO_POSITION=$2
    else
        echo "ERROR!!! Wrong Logo Position."
        echo
        echo "Available Logo Positions are:"
        echo "NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast"
        echo
        echo "EXITING."
        exit 1
    fi
fi

# Change to Directory with Original Photos
cd $1

if  [ -d "$WATERMARK_DIR" ]
then
    # Target Directory Already Exists.
    echo "Skipping Create Directory."

    if [ "$(ls -A $WATERMARK_DIR)" ]; then
        # Emptying Existing Directory.
        echo "Directory with Files Exists."
        echo "Removing existing Photos."
        rm "$WATERMARK_DIR"/*
    else
        echo "Empty Directory EXISTS."
    fi
else
    # create watermark output directory
    echo "Creating WaterMark Directory"
    mkdir "$WATERMARK_DIR"
fi

echo "Copying Original Files to New Directory"
# filename patterns which match no files to expand to a null string, rather than themselves.
shopt -s nullglob
# matches filenames in a case-insensitive fashion when performing filename expansion.
shopt -s nocaseglob

# Looping over whitelisted file types only,
# because I am assuming that source folder will contain
# files other than the photos too.
#
for file_type in ${PHOTO_TYPES[@]}
do
    echo "Copying all $file_type types"
    cp *."$file_type" "$1/$WATERMARK_DIR"
done

echo "Changing to Target Directory"
cd "$1/$WATERMARK_DIR" || { echo "Changing to $WATERMARK_DIR Directory FAILED."; exit 1; }

# Lowercase all file names
rename 'y/A-Z/a-z/' *

# Process all files from this directory
for fname in *.*; do
    # scale down image - minify
    # echo "Scaling $fname"
    # mogrify -scale 960x "$fname"

    # Rotate to Standard as per EXIF info
    echo "Rotating"
    exiftran -ia "$fname"

    # Add Watermark
    echo "Adding  watermark to $fname"
    composite -compose atop -gravity "$LOGO_POSITION" "$LOGO_PATH" "$fname" "$fname"

    # Remove EXIF Information from photos
    echo "EXIFTOOL: Processing $fname"
    exiftool -all= "$fname"

    # Deleting orignal file backups by exiftool
    rm *"original"
done

exit 0

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Header image courtesy https://www.pexels.com/photo/brown-film-133070/

Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.