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.
| Python |
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 | #!/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.


Comments
posixpath import. Is there any reason to directly import the posixpath module, instead of os.path? I think this recipe works on all plateformes...
Changed. Changed posixpath to os.path. Thanks :)
Use os.path.join(). Instead of
you may want to use
for more platform indepedent.
OK. Changed.
Python Image Library (PIL) extracts EXIF date in smaller amount of code:
Sample: http://code.activestate.com/recipes/576646/
Sign in to comment