Program © 2010-2024 Guillaume Dargaud.
Free use and distribution.
Last updated on 2019/07/04
"There are always two people in every picture: the photographer and the viewer." — Ansel Adams.
Here's a simple shell script that will display the aspect ratio of an image file, 100 being a square image. It can also be used to select and copy images that are within a certain range.
Here's a second similar shell script that will display the number of pixels of an image file. It can also be used to select and copy images that are within a certain range, and to make size conversions based on final number of pixels while maintaining aspect ratio.
Instructions:
$ MPix.sh -h USAGE: MPix.sh [Options] File [Files...] Gives the pixel count of an image (10 for 10 million pixels). OPTIONS: -n Display filenames but not the pixel count (used for selecting images in a range of pixels) -x Display pixel count but not the filenames -r Display 'MPix Filename' instead of 'Filename MPix', allowing you to pipe to 'sort -n' -m Pixel count is in megapixels (default) -k Pixel count is in kilopixels -p Pixel count is in pixels -g N Only display/copy if the pixel count is greater than the value given (inclusive) -l N Only display/copy if the pixel count is lower than the value given (inclusive) -c Dir Copy images that are within requested -g/-l values to a specific directory -t Nb When used in addition to -c, will downsize the image to a given [mega][kilo]pixel count (or simply copied if too small) EXAMPLES: MPix.sh -prg $((1024*768)) *.jpg | sort -n to sort images bigger than 1024x768 pixels by number of pixels MPix.sh -c /tmp/tv -t 2 -g 10 -l 12 *.png to copy and convert images in the 10~12 MPix range to 2 MPix in /tmp/tv
The bash shell built-in getopts is used to read command line parameters passed to a script. It can read single letter parameters, single letter parameters with a single argument, possibly repeated single letter parameters, possibly joined, but not long parameters. For instance, it can read: script -h -vv -f "my file" arg1 arg2, in that case the parameters are h, f and v (twice). But it can't read -long --long -f File1 File2... Here's how you can use it, with a simplified example:
#! /bin/bash function usage { cat << EOF USAGE: $0 [-v] [-h] [-f File] [args...] EOF } while getopts vf:h opt; do # 'opt' is the variable that will contain each letter in turn. # 'vf:h' describes the list of single letter parameters, # with a : if there's an optional argument (which ends up in $OPTARG) case $opt in v) echo "parameter -v";; # the order of vgh doesn't matter f) echo "parameter -f with argument $OPTARG";; # Here we make use of the argument passed along -f h) usage; exit 1;; ?) echo "Invalid option: -$OPTARG" >&2; exit 1;; esac done shift $(($OPTIND - 1)) # This is necessary so that now the remaining arguments end up as $1, $2... if [ $# -eq 0 ]; then usage; exit 1; fi # No other arguments, may or may not be a good thing while [ "$1" != "" ]; do echo "Argument: $1" # Now list all the remaining arguments shift # Next argument done
There are a few other options. For more info you can try help getopts since man doesn't usually work for builtins. And here's the result:
$ ./tmp -v parameter -v USAGE: ./tmp [-v] [-h] [-f File] [args...] $ ./tmp -vv -fFile1 -v -f "Big File" Arg1 Arg2 Arg3 parameter -v parameter -v parameter -f with argument File1 parameter -v parameter -f with argument Big File Argument: Arg1 Argument: Arg2 Argument: Arg3