Wednesday, July 23, 2008

Python Script to Rename and Sort Pictures by EXIF Date

Ok, today I had a set of pictures taken from a couple of different cameras and spread over a period of more than a year. Since the different cameras name the files differently the order in the directory is no longer chronological. Also since I've cropped or resized the pictures the timestamps on the files no longer represents when the picture was taken. So I wanted a way to rename the pictures so that they would be sorted by creation date.

I was already aware of the fairly useful Python module out there called EXIF.py (http://sourceforge.net/projects/exif-py/) so I downloaded the latest version and then whipped together a couple of quick scripts.

The first script was really just a test to make sure I was using the EXIF module correctly and helped me to learn a bit about it. It just dumps some of the EXIF data for each file given on the command line:



#!python

import EXIF
import sys

for filename in sys.argv[1:]:
try:
file=open(filename, 'rb')
except:
print "'%s': Cannot open for reading.\n" % filename
continue

# get the tags
data = EXIF.process_file(file, details=False, debug=False)
if not data:
print '%s: No EXIF data found' % filename
continue

date = data['Image DateTime']
model = data['Image Model']
res = data['Image XResolution']
unit = data['Image ResolutionUnit']
speed = data['EXIF ExposureTime']
fstop = data['EXIF FNumber']

assert(type(fstop.values[0] is EXIF.Ratio))
fstop = float(fstop.values[0].num) / float(fstop.values[0].den)

print "%s: %s, %s, %s %s, F%s %s sec" % (filename, date, model, res, unit, fstop, speed)

file.close()



So the above script can be used just to see things like the fstop and speed for each photo. Note however that there's very little error checking and I assume the appropriate tags are all there.

So a simple modification to the above script let's me rename all the files based on the time stamp so the new list is sorted by the date and time the picture was taken:



#!python

import EXIF
import sys
import os

list = {}

for filename in sys.argv[1:]:
try:
file=open(filename, 'rb')
except:
print "'%s': Cannot open for reading.\n" % filename
continue

# get the tags
data = EXIF.process_file(file, details=False, debug=False)
if not data:
print '%s: No EXIF data found' % filename
continue

date = data['Image DateTime']

key = str(date)
if key in list.keys():
print '%s: Duplicate datestamp with %s' % (filename, list[key])
list[key] = filename

file.close()

datestamps = list.keys()
datestamps.sort()
for datestamp in datestamps:
suffix = os.path.splitext(list[datestamp])[1]
newName = datestamp.replace(':', '_')
newName = newName.replace(' ', '_')
newName = "pic" + newName + suffix
try:
os.rename(list[datestamp], newName)
print list[datestamp] + ' -> ' + newName
except:
print '%s: Could not rename' % list[datestamp]



2 comments:

devost said...

Sweet! Just what I was looking for. Only suggestion would be to use:

date = data['EXIF DateTimeOriginal']

Instead of:

date = data['Image DateTime']

Dezza said...

Thank you, that worked really well. Same issue. It was easy to adjust to my needs. I had 2 cameras with different file naming systems. Remember to set your cameras date! It saves lots of headaches.