Batch convert images to sepia tone with python
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>
- Filed under coding, photography
- Tagged with photography, python, tips & tricks
- Comments(0)
