ASPN ActiveState Programmer Network  
ActiveState, a division of Sophos
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups
Submit Recipe
My Recipes

All Recipes
All Cookbooks


View by Category

Title: JPG files redater by EXIF data
Submitter: Michal Niklas (other recipes)
Last Updated: 2008/03/06
Version no: 1.3
Category: Files

 

Not Rated yet


Description:

Iterates through a directory, reading the EXIF data from each jpg.
Parses the date/time from EXIF data and if it differs from file
modification date/time then changes file date/time.

Source: Text Source

#!/usr/bin/python

__version__ = '$Id: exif_redater.py 470 2008-03-06 06:40:14Z mn $'

USAGE = "exif_redater.py\n\tredate .jpg/.jpeg files according to EXIF data"

"""
Iterates through a directory, reading the EXIF data from each jpg/jpeg file.
Parses the date/time from EXIF data and if it differs from file
modification date/time then changes file date/time

author: Michal Niklas
"""

import os
import os.path
import sys
import time

import EXIF

ALL_CNT = 0
CHANGED_CNT = 0

# which file should be checked
EXTENSIONS = ('.jpg', '.jpeg')

# what tags use to redate file (use first found)
DT_TAGS = ["Image DateTime", "EXIF DateTimeOriginal", "DateTime"]


def show_fdt(fdt):
	"""human readable format of file modification datetime"""
	return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(fdt))


def exif_info2time(ts):
	"""changes EXIF date ('2005:10:20 23:22:28') to number of seconds since 1970-01-01"""
	tpl = time.strptime(ts, '%Y:%m:%d %H:%M:%S')
	return time.mktime(tpl)


def redate_by_exif(fn):
	"""reads EXIF from jpg/jpeg and if file datetime differs from EXIF changes file date"""
	global ALL_CNT, CHANGED_CNT
	ALL_CNT += 1
	dt_value = None
	exif_time = None
	s = os.stat(fn)
	f = open(fn, 'rb')
	try:
		tags = EXIF.process_file(f)
		for dt_tag in DT_TAGS:
			try:
				dt_value = "%s" % tags[dt_tag]
				break
			except:
				continue
		if dt_value:
			file_time = s[8]
			exif_time = exif_info2time(dt_value)
	finally:
		f.close()
	if exif_time:
		secs_diff = file_time - exif_time
		MAX_DIFF = 130.0
		if secs_diff > MAX_DIFF or secs_diff < -MAX_DIFF:
			print "%s    %s -> %s" % (fn, show_fdt(file_time), show_fdt(exif_time))
			os.utime(fn, (exif_time, exif_time))
			CHANGED_CNT += 1


def process_dir(_, dir_name, files):
	"""looks for .jpg/.jpeg file in dir"""
	for fname in files:
		can_change = False
		fnl = fname.lower()
		for ext in EXTENSIONS:
			if fnl.endswith(ext):
				can_change = True
				break
		if can_change:
			fname = os.path.join(dir_name, fname)
			if os.path.isfile(fname):
				try:
					redate_by_exif(fname)
				except:
					pass


def main():
	os.path.walk('.', process_dir, None)
	print '\nChecked: %d\nChanged %d\n' % (ALL_CNT, CHANGED_CNT)


if '--version' in sys.argv:
	print __version__
else:
	if __name__ == '__main__':
		if '--help' in sys.argv:
			print USAGE
		else:
			main()

Discussion:

Needs EXIF.py (from sourceforge, tested with VERSION 1.0.7)

Chnaged posixpath to os.path. Thanks Frederic Mantegazza :)

I also extended EXIF tags to look for. My Canon writes "Image DateTime" while hp photosmart 120 does not, but hp writes "EXIF DateTimeOriginal". You should check what tags you camera writes.



Add comment

Number of comments: 4

posixpath import, Frederic Mantegazza, 2008/03/04
Is there any reason to directly import the posixpath module, instead of os.path? I think this recipe works on all plateformes...
Add comment

Changed, Michal Niklas, 2008/03/04
Changed posixpath to os.path. Thanks :)
Add comment

Use os.path.join(), Jean Brouwers, 2008/03/05
Instead of

			fname = dir_name + '/' + fname
you may want to use
			fname = os.path.join(dir_name, fname)
for more platform indepedent.
Add comment

OK, Michal Niklas, 2008/03/05
Changed.
Add comment



Highest rated recipes:

1. A simple XML-RPC server

2. Web service accessible ...

3. Treat the Win32 Registry ...

4. Watching a directory ...

5. Union Find data structure

6. Function Decorators by ...

7. MS SQL Server log monitor

8. Table objects with ...

9. wx twisted support using ...

10. More accurate sum




Privacy Policy | Email Opt-out | Feedback | Syndication
© 2006 ActiveState Software Inc. All rights reserved.