Digital cameras generally name their files DSC00001.JPG or something silly like that. I prefer that have them named according to the shooting data first, and possibly some additional information thereafter so that they sort by time taken. Fortunately the EXIF information contains the shooting data, so it is just a matter of extracting it from the file and renaming it. There is a slight complication: some cameras can take more than one shot per second, but they typically only provide the EXIF information with second-granularity, so we have to deal with this.
In [1]:
#!wget https://www.dropbox.com/s/-/DSC00005.JPG
#!cp DSC00005.JPG IMAGE.jpg
!cp IMAGE.jpg DSC00005.JPG
!ls -l *.JPG
In [2]:
from PIL import Image,ExifTags
from datetime import datetime as dt
import pytz
class exif:
def __init__(self, fn, tz=None, fmt_str=None):
self.fn = fn
if tz == None: tz = 'Europe/London'
self.timezone = pytz.timezone(tz)
if fmt_str == None: fmt_str = '%Y:%m:%d %H:%M:%S'
self.fmt_str = fmt_str
img = img = Image.open(fn)
self.data = {
ExifTags.TAGS[k]: v
for k, v in img._getexif().items()
if k in ExifTags.TAGS
}
dto = dt.strptime(self.data['DateTime'], fmt_str)
self.data['DateTime_o'] = self.timezone.localize(dto)
dto = dt.strptime(self.data['DateTimeOriginal'], fmt_str)
self.data['DateTimeOrignal_o'] = self.timezone.localize(dto)
dto = dt.strptime(self.data['DateTimeDigitized'], fmt_str)
self.data['DateTimeDigitized_o'] = self.timezone.localize(dto)
def time (self, fmt=None, which_time=None, tz=None):
if fmt == None: fmt = "%Y%m%d_%H%M%S"
if which_time == None: which_time = 'DateTime'
dto = self.data[which_time+"_o"];
if tz:
timezone = pytz.timezone(tz)
dto = timezone.normalize(dto.astimezone(timezone))
if fmt == False: return dto
return dto.strftime(fmt)
In [2]:
In [3]:
e = exif('DSC00005.JPG')
e.data['MakerNote'] = ""
e.data['UserComment'] = ""
e.data
Out[3]:
In [4]:
type(e.time())
Out[4]:
In [5]:
e.time()
Out[5]:
In [6]:
import glob
def exifRename (fmt1=None, pattern=None, fmt=None, dryrun=False):
if fmt==None: fmt='%Y%m%d_%H%M%S_'
if pattern==None: pattern='DSC*.JPG'
files = glob.glob(pattern)
flist = []
for fn in files:
fn2 = 'test'
e = exif(fn)
fn2a = e.time(fmt)
if fmt1 == None: fn2 = fn2a + fn
else: fn2 = fn2a + fmt1
flist.append((fn, fn2))
if dryrun==True: return flist
for oldfn, newfn in flist:
!mv $oldfn $newfn
return flist
In [7]:
exifRename()
Out[7]:
In [8]:
!ls -l *.JPG
In [8]: