- Calazan.com - http://www.calazan.com -

Python script for auto-renaming your image files

Posted By webmaster On January 19, 2012 @ 12:36 am In Development | No Comments

I like to rename my pictures a certain way as soon as I import them to my computer.  I usually follow this format: description_datetaken_3digitnumbering.jpg

I was using Metamorphose to do this for a while.  But one time I wanted to rename my pictures while I was in New Zealand and realized I didn’t have the application installed on my netbook.  I didn’t want to pay the $5 for the Internet access so I decided to just hack together a simple Python script to do it.  I haven’t gone back to Metamorphose ever since.  I found my script easier to use as I had it customized for my needs.

I’ve tweaked it quite a bit to make it even more user friendly.  Here’s the script if you’re interested. Note that I’m not sure whether the EXIF tag attributes are the same for your camera, so you might need to modify it a little to work for you.

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

# Check first if the given path exists before continuing to the next step.
while True:
    folderpath = raw_input('Folder path: ')
    print "\nChecking if folder path exists...\n"
    if os.path.exists(folderpath):
        print "Ok!\n"
        break;
    else:
        print "%s does not exist. Please enter a valid path.\n" % folderpath

filename_pattern = raw_input('Filename pattern: ')

def get_exif_data(filename):
    """Get embedded EXIF data from image file.

    Source: http://www.endlesslycurious.com/2011/05/11/extracting-image-
            exif-data-with-python/
    """
    ret = {}
    try:
        img = Image.open(filename)
        if hasattr( img, '_getexif' ):
            exifinfo = img._getexif()
            if exifinfo != None:
                for tag, value in exifinfo.items():
                    decoded = TAGS.get(tag, tag)
                    ret[decoded] = value
    except IOError:
        print 'IOERROR ' + filename
    return ret

def get_date_taken(filename):
    datestring = get_exif_data(current_file)['DateTimeOriginal']
    return datetime.datetime.strptime(datestring, '%Y:%m:%d %H:%M:%S')

def get_filenames():
    os.chdir(folderpath)
    return os.listdir(os.getcwd())

def get_numbering_format(digits, num):
    if digits == 1:
        numberfmt = '00%s' % num
    elif digits == 2:
        numberfmt = '0%s' % num
    else:
        numberfmt = '%s' % num
    return numberfmt

def date_to_string(dateobj, format):
    return datetime.datetime.strftime(dateobj, format)

def multi_replace(text, dictobj):
    """Replace characters in the text based on the given dictionary."""
    for k, v in dictobj.iteritems():
        text = text.replace(k, v)
    return text

if __name__ == '__main__':
    filenames = get_filenames()
    for i in xrange(len(filenames)):
        num = i + 1
        digits = len(str(num))
        current_file = filenames[i]

        # Only rename files, ignore directories.
        if not os.path.isdir(current_file):
            # Key, value pairs of what to replace.
            dictobj = {
                '<num>': get_numbering_format(digits, num),
                '<datetaken>': date_to_string(get_date_taken(current_file),
                                              '%Y%m%d')
            }
            new_filename = multi_replace(filename_pattern, dictobj)
            shutil.move(current_file, new_filename)

Sample Usage

Notes

  • PIL (Python Imaging Library) is required to retrieve the EXIF data.
  • I decided not to traverse subdirectories as that could be pretty dangerous if the wrong path is accidentally entered.
  • It’s set to pad the numbering to 3 digits.
  • It will rename any file that is not a directory (maybe add a check later for file type).

Article printed from Calazan.com: http://www.calazan.com

URL to article: http://www.calazan.com/python-script-for-auto-renaming-your-image-files/

Copyright © 2010 Calazan.com. All rights reserved.