Welcome, guest | Sign In | My Account | Store | Cart

Rename JPEG files according to EXIF-date using PIL [library].

If global variable CREATE_HARDLINK is set, script creates Windows (XP) batch file for creating hardlink version of source files.

PIL available here: http://www.pythonware.com/products/pil/

Python, 111 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
# -*- coding: Windows-1251 -*-
'''
rename_to_exiftime.py

Rename JPEG files according to EXIF-date using PIL

If global variable CREATE_HARDLINK is set, script creates Windows (XP) batch file 
for creating hardlink version of source files

Author: Denis Barmenkov <denis.barmenkov@gmail.com>

Copyright: this code is free, but if you want to use it, 
           please keep this multiline comment along with function source. 
           Thank you.

2009-02-10 18:14 
'''

import Image

import os
import re
import sys
import time

CREATE_HARDLINK=0

def extract_jpeg_exif_time(jpegfn):
    if not os.path.isfile(jpegfn):
        return None
    try:
        im = Image.open(jpegfn)
        if hasattr(im, '_getexif'):
            exifdata = im._getexif()
            ctime = exifdata[0x9003]
            #print ctime
            return ctime
    except: 
        _type, value, traceback = sys.exc_info()
        print "Error:\n%r", value
    
    return None

def get_exif_prefix(jpegfn):
    ctime = extract_jpeg_exif_time(jpegfn)
    if ctime is None:
        return None
    ctime = ctime.replace(':', '')
    ctime = re.sub('[^\d]+', '_', ctime)
    return ctime

def rename_jpeg_file(fn):
    if not os.path.isfile(fn):
        return 0
    ext = os.path.splitext(fn)[1].lower()
    if ext not in ['.jpg', '.jpeg', '.jfif']:
        return 0
    path, base = os.path.split(fn)
    print base # status
    prefix = get_exif_prefix(fn)
    if prefix is None:
        return 0
    if base.startswith(prefix): 
        return 0 # file already renamed to this prefix

    new_name = prefix + '_' + base
    new_full_name = os.path.join(path, new_name)

    if CREATE_HARDLINK:
        f = open('CREATE_HARDLINK.cmd', 'a')
        f.write('fsutil hardlink create "%s" "%s"\n' % (new_full_name, fn))
        f.close()
    else:
        try:
            os.rename(fn, new_full_name)
        except:
            print 'ERROR rename %s --> %s' % (fn, new_full_name)
            return 0

    return 1

def rename_jpeg_files_in_dir(dn):
    names = os.listdir(dn)
    count=0
    for n in names:
        file_path = os.path.join(dn, n)
        count += rename_jpeg_file(file_path)
    return count


if __name__=='__main__':
    try:
        path = sys.argv[1]
    except IndexError:
        print '''Usage:  

  rename_to_exiftime.py  filename.[jpeg|jpg|jfif]

or

  rename_to_exiftime.py  dirname
'''
        sys.exit(1)

    if os.path.isfile(path):
        rename_jpeg_file(path)
    elif os.path.isdir(path):
        count = rename_jpeg_files_in_dir(path)
        print '%d file(s) renamed.' % count
    else:
        print 'ERROR: path not found: %s' % path
        

Some time ago I've got few photo series taken at same time by different peoples. Each photo camera has its own picture naming rules, so I wrote this script for sorting photos by date/time from EXIF.

5 comments

sal_m 15 years, 2 months ago  # | flag

I use a shell script to rename files based on the exif date and camera.

I find it useful to automatically add xx-1.jpg or xx-2.jpg when I have more than one picture taken at the same time (within a second of each other). Especially when the camera is set to take multiple pictures sequentially.

Jorge Barnaby 11 years, 9 months ago  # | flag

Thanks for the recipe, it's great! I've been using it for the several months now, with a minor improvement on renaming duplicated files (for example, two photos taken on the same second): http://code.activestate.com/recipes/578219/

Lukaz 10 years, 9 months ago  # | flag

Denis thank you so much. Your example is actually the only working one I searched in past 24 hours. Great stuff!!!

Gareth Newman 10 years ago  # | flag

I thought to myself, I wonder if I can write a script in python to rename images based on date taken.... this was the first google hit and it works abosolutely perfect!! Thanks for taking the time to write this.

Vagelis Prokopiou 8 years, 1 month ago  # | flag

Very nice little program. Thank you!