Recently I needed a script to batch convert only those images amongst a large amount of images which fulfil certain criteria, namely of being exactly of a stated size. The script is based on ImageMagick’s convert and basically takes an arbitrary amount of convert parameters. I personally use this script to automatically reduce size and quality of photos taken with a specific camera in order to reduce their hard disk space coverage.
The script
#! /usr/bin/python # # convertconditional: Convert an image if it fulfills certain conditions, e.g. is of a certain size. Requires ImageMagick's convert. # Rainhard Findling 2013/08 # # example to convert all *JPG within the current directory with are of certain size to a reduced size and quality: # find . -iname "*JPG" -exec ./convertconditional {} -filtersize 3888x2592 -convertparams "-resize 3500x3000 +repage -quality 80" \; # import argparse # check http://docs.python.org/2/howto/argparse.html for help import subprocess import sys # specify arguments parser = argparse.ArgumentParser() parser.add_argument('inputfile', help='path to the file that will be converted.') parser.add_argument('-convertparams', required=True, help='parameters handed to the convert command used internally, e.g. resize, repage, reduce quality etc. Example: "-resize 300x200 +replage -quality 92"') parser.add_argument('-filtersize', help='only convert if original image is of this size, stated as WIDTHxHEIGHT, e.g. 3500x3200.') parser.add_argument('-o', '--outputfile', help='path to where the converted image will be stored. if not specified, the original file will be overwritten.') parser.add_argument('-v','--verbose',help='print verbose output.',action='store_true') args = parser.parse_args() # make sure we can process names with spaces args.inputfile = '"' + args.inputfile + '"' # check for correct arguments if not args.outputfile: args.outputfile = args.inputfile if args.filtersize: filter_x = int(args.filtersize.split('x')[0]) filter_y = int(args.filtersize.split('x')[1]) if args.verbose: print 'inputfile=' + args.inputfile print 'outputfile=' + args.outputfile if args.filtersize: print 'resizing only', str(filter_x) + 'x' + str(filter_y), 'images.' print 'convertparams=' + args.convertparams # get size of image imagesize = subprocess.check_output(["identify -format '%wx%h' " + args.inputfile], stderr=subprocess.STDOUT, shell=True) imagesize_x = int(imagesize.split('x')[0]) imagesize_y = int(imagesize.split('x')[1]) # condition: filter for images of certain size if args.filtersize: if args.verbose: print 'size of', args.inputfile, 'is', str(imagesize_x) + "x" + str(imagesize_y) # check filter criteria if not imagesize_x == filter_x or not imagesize_y == filter_y: print 'leaving out ' + args.inputfile + ' as it is of size ' + str(imagesize_x) + "x" + str(imagesize_y) + " (required: " + args.filtersize + ")" sys.exit(0) # passed all conditions: convert image print 'converting ' + args.inputfile + ' (size: ' + str(imagesize_x) + "x" + str(imagesize_y) + ')' # convert image command="convert " + args.inputfile + " " + args.convertparams + " " + args.outputfile if args.verbose: print 'command:', command imagesize = subprocess.check_output([command], stderr=subprocess.STDOUT, shell=True)
The script is written in Python, so all you need to do is save it (e.g. in a file called “convertconditional”) and make it executable:
chmod +x convertconditional
Then you can either call it with stating it’s path (e.g. “./convertconditional [parameters]“), or add it to your systems PATH to call it from everyhwere.
Script execution
In order to convert input.jpg to output.jpg, you can try
convertconditional input.jpg -filtersize 3888x2592 -convertparams "-resize 3500x3000 +repage -quality 85" -o output.jpg
- -filtersize optional filtering: only convert the image in case it is exactly of the stated size
- -convertparams states parameters which should be handed to ImageMagick’s convert
- -o states where to store the converted image (original image gets overwritten if omitted)
In case you want to conditionally convert multiple files (as with my usecase) you can combine convertconditional with find and overwrite the original files:
find . -iname "*JPG" -exec convertconditional {} -filtersize 3888x2592 -convertparams "-resize 3500x3000 +repage -quality 85" \;
