|
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
__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
EXTENSIONS = ('.jpg', '.jpeg')
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
|
|
|