Quantcast
Channel: Mike's Blabberings » photography
Viewing all articles
Browse latest Browse all 4

Batch convert images to sepia tone with python

$
0
0

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>


Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles





Latest Images