The Python Imaging Library (PIL) offers easy photo manipulation from python scripts. There’s some handy sample code on effbot.org that demonstrates how to alter an image’s palette to generate a sepia tone effect. It first desaturates the image, then applies a new palette based on a linear ramp.
I’ve cleanup up that sample code and tucked it into a script. You can pass a list of files to the script, and it will apply a sepia effect to each, making sure to backup the originals.
#!/usr/bin/python """ Apply sepia filter in batch to images Usage: python batch_sepia.py [--no-backup] file1 [file2] ... """ import Image as PIL_Image import shutil, os from optparse import OptionParser def open_image(filename): """ grab a PIL image from the given location """ image = PIL_Image.open(filename) image.load() return image def save_image(image, filename, quality=95): """ save the PIL image to disk """ image.save(filename, "JPEG", quality=quality) def make_linear_ramp(white): """ generate a palette in a format acceptable for `putpalette`, which expects [r,g,b,r,g,b,...] """ ramp = [] r, g, b = white for i in range(255): ramp.extend((r*i/255, g*i/255, b*i/255)) return ramp def apply_sepia_filter(image): """ Apply a sepia-tone filter to the given PIL Image Based on code at: http://effbot.org/zone/pil-sepia.htm """ # make sepia ramp (tweak color as necessary) sepia = make_linear_ramp((255, 240, 192)) # convert to grayscale orig_mode = image.mode if orig_mode != "L": image = image.convert("L") # optional: apply contrast enhancement here, e.g. #image = ImageOps.autocontrast(image) # apply sepia palette image.putpalette(sepia) # convert back to its original mode if orig_mode != "L": image = image.convert(orig_mode) return image def convert_image(filename, make_backup): """ convert an image at the given path to sepia tone. @param filename @param make_backup - if True, will copy original file to file.bak """ if not os.path.exists(filename): print 'Skipping %s' % filename return print 'Processing %s...' % filename if make_backup: shutil.copyfile(filename, '%s.bak' % filename) save_image(apply_sepia_filter(open_image(filename)), filename) print 'Done.' def convert_images(files, make_backup=True): """ convert the list of filenames to sepia tone. @param filename @param make_backup - if True, will copy original file to file.bak """ map(lambda f: convert_image(f, make_backup), files) if __name__ == '__main__': parser = OptionParser() parser.add_option("-x", "--no-backup", dest="no_backup", default=False, action="store_true") (options, files) = parser.parse_args() convert_images(files, make_backup=not options.no_backup)
You can execute this from the command line as:
$ python batch_sepia.py image1.jpg image2.jpg image3.jpg
If you want to recursively apply the filter to a bunch of images, you might consider mixing this with some find/xargs-fu:
$ find $HOME/pictures -name "*.jpg" | xargs python batch_sepia.py
Once you’ve got your photos in order, head over to photoworks.com to get them printed!</shameless-plug>