Created
September 14, 2011 09:52
-
-
Save glasserc/1216217 to your computer and use it in GitHub Desktop.
Program to adjust dates on EXIF tags for a bunch of JPEG files using python-exif and exiftool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python | |
"""Program to fix my screwed up camera date/time settings. | |
At some point, some children adjusted the date on my camera as well as | |
the locale settings. Photos were henceforth marked as being one day | |
earlier than they should have been (i.e. the 28th instead of the 29th). | |
Later, I noticed that the camera date was wrong, but because the | |
equivalent of LC_DATE was different, I thought it was one MONTH early | |
instead of one DAY. I "fixed" it by putting the date on the camera | |
one month forward. | |
Eventually I noticed that the date was even more wrong, put the camera | |
back in en-US, and quietly panicked because all of the EXIF date tags | |
were screwed up on my images. | |
This script is meant to adjust the dates on all images to accord with | |
what I think is the correct date. | |
Starting at (possibly earlier?) DSCN8367.JPG, photos are one day | |
behind when they should be: May 28th instead of May 29th. This | |
continues through DSCN8580.JPG, which is June 6th but should be June | |
7th. I "fixed" it by adding one month but not one day: DSCN8581.JPG | |
says July 9th, but should be June 10th (a difference of 29 days). | |
This continues through DSCN8981.JPG. DSCN8982.JPG jumps back 27 days | |
(presumably two days after the last photo).""" | |
import sys | |
import os | |
import re | |
import subprocess | |
import datetime | |
import EXIF | |
FILENAME_RE = re.compile("dscn(\\d+)\\.jpg", re.I) | |
EXIF_TS_FORMAT = "%Y:%m:%d %H:%M:%S" | |
def photo_number(fname): | |
match = FILENAME_RE.match(fname) | |
if not match: return None | |
return int(match.group(1)) | |
def to_exif(ts): | |
return ts.strftime(EXIF_TS_FORMAT) | |
def from_exif(tag): | |
return datetime.datetime.strptime(str(tag), EXIF_TS_FORMAT) | |
def adjust_date(fname, delta): | |
f = open(fname, 'rb') | |
tags = EXIF.process_file(f) | |
#dump_tags(fname, tags) | |
date = from_exif(tags['EXIF DateTimeOriginal']) | |
assert date == from_exif(tags['Image DateTime']) | |
assert date == from_exif(tags['EXIF DateTimeDigitized']) | |
args = ['exiftool', fname] | |
for tag in ['DateTimeOriginal', 'CreateDate', 'ModifyDate']: | |
args.append('-{0}={1}'.format(tag, to_exif(date+delta))) | |
args.append('-FileModifyDate={0}-04:00'.format(to_exif(date+delta))) | |
print "{0}: {1} {2}".format(fname, date, date+delta) | |
print args | |
retcode = subprocess.check_call(args, executable="/usr/bin/exiftool", stdout=sys.stdout, stderr=sys.stderr) | |
#print "{0}: {1}".format(fname, tags['Image Orientation']) | |
def dump_tags(fname, tags): | |
print fname | |
for tag in tags.keys(): | |
if tag not in ('JPEGThumbnail', 'TIFFThumbnail', 'Filename', | |
'EXIF MakerNote'): | |
try: | |
str(tags[tag]) | |
except TypeError: | |
print "Couldn't stringify {0}: {1}".format(tag, tags[tag].__class__) | |
continue | |
print "Key: {0}, value {1}, type {2}".format(tag, tags[tag], tags[tag].__class__) | |
if __name__ == '__main__': | |
dir = os.listdir(".") | |
dir.sort() | |
#dir = dir[:1] | |
# Used to bump up pictures that were a day behind. | |
forward_delta = datetime.timedelta(days=1) | |
# Used to bump back pictures that were almost a month ahead. | |
backwards_delta = datetime.timedelta(days=-29) | |
for fname in dir: | |
num = photo_number(fname) | |
if num == None: continue # skip *-resize.jpg | |
if 8367 <= num <= 8580: | |
adjust_date(fname, forward_delta) | |
elif 8581 <= num <= 8981: | |
adjust_date(fname, backwards_delta) | |
else: | |
print "{0} is not in the affected range; leaving unchanged".format(fname) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment