photo2mail

Digital cameras today tend to produce very large image files. Files unsuitable for inclusion in email messages and other forms of online communication. This script solves that problem by reading one or more image files then writing new files with a more appropriate size. It does this with the help of the convert program supplied with the ImageMagick package.

Examples

me@linuxbox ~ $ photo2mail image.jpg

In its simplest form, photo2mail reads the file image.jpg and creates a new image file called image-1024.jpg in the same directory as the original.

me@linuxbox ~ $ photo2mail -s 800 image.jpg

By default, the script resizes images to fit within a square bounding box 1024 pixels in size. By using the -s option, other sizes can be specified.

me@linuxbox ~ $ photo2mail -d ../resized image.jpg

By including the -d option, an alternate directory for output can be specified.

me@linuxbox ~ $ photo2mail -j image.png

By default, photo2mail writes the resized image in the same file format as the original. The -j option forces photo2mail to write a JPEG file instead.

Listing

#!/bin/bash
# ---------------------------------------------------------------------------
# photo2mail - Resize images for use as email attachments

# Copyright 2013, William Shotts <bshotts@users.sourceforge.net>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License at <http://www.gnu.org/licenses/> for
# more details.

# Usage: photo2mail [-h|--help] [--options] file...

# Options:
# -d, --directory dir   Directory for output images. Default
#                       is same directory as source.
# -j, --jpeg            Force output image to be JPEG regardless
#                       of source image format.
# -s, --size size       Size of output image bounding box. Default
#                       is 1024 pixels.

# This program produces resized images from originals using the 'convert'
# program from the ImageMagick suite. Output images are created in the
# same directory as the originals and have the image size appended to
# their names for easy identification. The 'size' argument is the
# width, in pixels, of the square bounding box containing the resized
# image.

# Revision history:
# 2014-01-12  More cleanups (1.2)
# 2014-01-04  Various cleanups (1.1)
# 2013-01-11  Created by new_script ver. 3.0.1
# ---------------------------------------------------------------------------

PROGNAME=${0##*/}
VERSION="1.2"
DEFAULT_SIZE=1024
REQUIRED_PROGS="identify convert"

clean_up() { # Perform pre-exit housekeeping
  return
}

error_exit() {
  echo -e "${PROGNAME}: ${1:-"Unknown Error"}" >&2
  clean_up
  exit 1
}

error_warning() {
  echo -e "${PROGNAME}: Warning - $1" >&2
  return
}

graceful_exit() {
  clean_up
  exit
}

signal_exit() { # Handle trapped signals
  case $1 in
    INT)    error_exit "Program interrupted by user" ;;
    TERM)   echo -e "\n$PROGNAME: Program terminated" >&2
            graceful_exit ;;
    *)      error_exit "$PROGNAME: Terminating on unknown signal" ;;
  esac
}

usage() {
  echo -e "Usage: $PROGNAME [-h|--help] [--options] file..."
}

help_message() {
  cat << _EOF_
$PROGNAME ver. $VERSION
Resize images for use as email attachments

$(usage)

Options:
-d, --directory dir Directory for output images. Default
                    is same directory as source.
-j, --jpeg          Force output image to be JPEG regardless
                    of source image format.
-s, --size size     Size of output image bounding box. Default
                    is 1024 pixels.

_EOF_
  return
}

# Trap signals
trap "signal_exit TERM" TERM HUP
trap "signal_exit INT"  INT

size=$DEFAULT_SIZE
f_ext=
f_path=

# Parse command-line
while [[ -n $1 ]]; do
  case $1 in
    -d | --directory) shift; f_path="$1" ;;
    -h | --help)      help_message; graceful_exit ;;
    -j | --jpeg)      f_ext="jpg" ;;
    -s | --size)      shift; size="$1" ;;
    -* | --*)         usage; error_exit "Unknown option $1" ;;
    *)                break ;;
  esac
  shift
done

# Main logic

# Check validity of options
[[ "$size" =~ ^[0-9]+$ ]] \
  || error_exit "output size must be an integer."
[[ -z "$f_path" || -d "$f_path" ]] \
  || error_exit "output directory '$f_path' does not exist."

# Make sure that required ImageMagick programs are installed
for i in $REQUIRED_PROGS; do
  type "$i" &> /dev/null \
    || error_exit "required program '$i' not found."
done

# Processing loop
for input_file in "$@"; do
  if [[ -r "$input_file" ]] && identify "$input_file" &> /dev/null; then
    filename="${input_file##*/}"
    if [[ -z "$f_path" ]]; then
      path="${input_file%/*}"
    else
      path="$f_path"
    fi
    [[ "$filename" == "$path" ]] && path="."
    base="${filename%.*}"
    if [[ -z "$f_ext" ]]; then
      ext="${filename##*.}"
    else
      ext="$f_ext"
    fi
    output_file="$path/$base-$size.$ext"
    convert "$input_file" -resize ${size}x${size} "$output_file" \
      || error_warning "Cannot convert '$input_file'. Skipping..."
  else
    error_warning "'$input_file' not a valid image file. Skipping..."
  fi
done

graceful_exit