Creating thumbnails from photos with Python PIL

This time around I want to share with you a little Python library I found called PIL. If you’re a Python developer chances are you already know of it, but I use Python only from time to time, usually to automate some tasks so I was very excited to come across such a library. First thing’s first, download PIL and install it. I’m using it on a Windows platform so I used the packaged binary version, but you can get the source code and use it on any platform that supports Python. There’s also links to documentation on the same page. If you already know Python it should be fairly easy to use the library. What I liked best about it is speed, though my comparison is to Java-based image processing which can be painfully slow. One of the first things I did with it was create a simple little thumbnail generator to help me handle my photo collection which you can see below. Simply specify a directory with .jpg files in it and the script will go through each file, shrink it to fit a chosen format of 1024×768 while maintaining the aspect ratio and create a thumbnail for it. All the created files are placed in a directory named album which is relative to your working directory. Oh, almost forgot, it tries to read the EXIF data of the photos and if Orientation tag is found it automatically rotates the image for your viewing pleasure.

import os
import sys
import Image
from PIL import Image
from PIL.ExifTags import TAGS

albumdir = 'album'
thumbdir = albumdir + '/thumbs'

def mkdir(dirname):

def maxSize(image, maxSize, method = 3):
  imAspect = float(image.size[0])/float(image.size[1])
  outAspect = float(maxSize[0])/float(maxSize[1])

  if imAspect >= outAspect:
    return image.resize((maxSize[0], int((float(maxSize[0])/imAspect) + 0.5)), method)
    return image.resize((int((float(maxSize[1])*imAspect) + 0.5), maxSize[1]), method)

def processImage(imgdir, fname):
  img = + fname)
  exif = img._getexif()
  if exif != None:
    for tag, value in exif.items():
      decoded = TAGS.get(tag, tag)
      if decoded == 'Orientation':
        if value == 3: img = img.rotate(180)
        if value == 6: img = img.rotate(270)
        if value == 8: img = img.rotate(90)
  img = maxSize(img, (1024, 768), Image.ANTIALIAS) + '/' + fname, 'JPEG', quality=100)
  img.thumbnail((192, 192), Image.ANTIALIAS) + '/' + fname, 'JPEG')

def main():
  if len(sys.argv) < 2:
    print "Usage: imgdir"
    imgdir = sys.argv[1] + '/'

  files = os.listdir(imgdir)

  for fname in files:
    if fname.lower().endswith('.jpg'):
      processImage(imgdir, fname)

  print 'done'

if __name__ == "__main__":

Google for some PIL tutorials to learn more, there are some nice pages out there like this one.