rename files to match their EXIF “Date Taken”?

1767
7
Jump to solution
04-16-2019 09:05 AM
JaredPilbeam2
MVP Regular Contributor

I need some help putting the date in the filenames. Here's the working code I have so far. 

import arcpy, sys
import exifread
from exifread import exif
import os
import time
from datetime import datetime

im = r"path\to\DOT_SignInventory"

for root, dirnames, filenames in os.walk(im): #iterate directory
    for fname in filenames:
        if fname.endswith('.JPG'):
            with open(os.path.join(root, fname), 'rb') as image: #file path and name
                exif = exifread.process_file(image)
                dt = str(exif['EXIF DateTimeOriginal']) #get 'Date Taken' from JPG
                ds = time.strptime(dt, '%Y:%m:%d %H:%M:%S')
                nt = time.strftime("%m/%d/%Y",ds)#variable with 'Date Taken'
                print("Photo:{} Date Taken:{}".format(fname, "_" + nt))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I've tried these couple things after the print statement, but no cigar:

new_file = fname + nt + ".jpg"
f = open(fname.format(nt), "w")
f.write(fname + nt)
f.close‍‍‍
Tags (3)
0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Regular Contributor

You will also need to close the file before renaming it.  Perhaps:

for root, dirnames, filenames in os.walk(im): #iterate directory
    for fname in filenames:
        if fname.endswith('.JPG'):
            with open(os.path.join(root, fname), 'rb') as image: #file path and name
                exif = exifread.process_file(image)
                dt = str(exif['EXIF DateTimeOriginal']) #get 'Date Taken' from JPG
                ds = time.strptime(dt, '%Y:%m:%d %H:%M:%S')
                nt = time.strftime("%Y-%m-%d",ds)
                newname = fname[0:7] + "_" + nt + ".jpg"
            image.close()
            os.rename(os.path.join(root,fname), os.path.join(root,newname))

View solution in original post

0 Kudos
7 Replies
RandyBurton
MVP Regular Contributor

Here's a snippet that shows some options:

jpg = 'file.jpg'
fn = jpg.split('.')[0] # first part of jpg name by splitting on dot
print fn
# file

exif = '2018:06:05 13:49:40' # date/time from exif data
exifdt = exif.replace(':','-').replace(' ','_') # replace colons and space
print exifdt
# 2018-06-05_13-49-40

newname = fn+"_"+exifdt+".jpg"
print newname
# file_2018-06-05_13-49-40.jpg‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

You could split the exif data on the space to remove the time.  However, including time may be useful in preventing duplicate file names.  Also, I like dates in the year-month-day format as it helps sorting, but that is a personal preference.

Hope this helps.

RandyBurton
MVP Regular Contributor

And to do the actual renaming, try something like

os.rename(os.path.join(root,fname), os.path.join(root,newname))
0 Kudos
JaredPilbeam2
MVP Regular Contributor

Randy,

I tried:

newname = fname[0:7] + "_" + nt + ".jpg"
os.rename(os.path.join(root,fname), os.path.join(root,newname))

Even within the with loop it's throwing a Permission Error:

PermissionError: [WinError 32] The process cannot access the file 
because it is being used by another process:
'path\\to\\DOT_SignInventory\\CH01\\0100010.JPG' -> 
'path\\to\\DOT_SignInventory\\CH01\\0100010_04/27/2018.jpg'‍‍‍‍‍‍‍‍‍‍
0 Kudos
RandyBurton
MVP Regular Contributor

You need to change the slashes in the date to either dashes or underscore. Slashes are used to separate directories in the path, so they cannot be used in a file name.

# change this
nt = time.strftime("%m/%d/%Y",ds)#variable with 'Date Taken'

# to
nt = time.strftime("%m-%d-%Y",ds)

# or
nt = time.strftime("%m_%d_%Y",ds)‍‍‍‍‍‍‍‍
JaredPilbeam2
MVP Regular Contributor

Tried both options, and also tried '%Y%m%d'. Still throwing the PermissionError. Here's what I have:

import arcpy, sys
import exifread
from exifread import exif
import os
import time
from datetime import datetime

im = "path\to\DOT_SignInventory"

for root, dirnames, filenames in os.walk(im): #iterate directory
    for fname in filenames:
        if fname.endswith('.JPG'):
            with open(os.path.join(root, fname), 'rb') as image: #file path and name
                exif = exifread.process_file(image)
                dt = str(exif['EXIF DateTimeOriginal']) #get 'Date Taken' from JPG
                ds = time.strptime(dt, '%Y:%m:%d %H:%M:%S')
                nt = time.strftime("%Y-%m-%d",ds)
                newname = fname[0:7] + "_" + nt + ".jpg"
                os.rename(os.path.join(root,fname), newname)
0 Kudos
RandyBurton
MVP Regular Contributor

You will also need to close the file before renaming it.  Perhaps:

for root, dirnames, filenames in os.walk(im): #iterate directory
    for fname in filenames:
        if fname.endswith('.JPG'):
            with open(os.path.join(root, fname), 'rb') as image: #file path and name
                exif = exifread.process_file(image)
                dt = str(exif['EXIF DateTimeOriginal']) #get 'Date Taken' from JPG
                ds = time.strptime(dt, '%Y:%m:%d %H:%M:%S')
                nt = time.strftime("%Y-%m-%d",ds)
                newname = fname[0:7] + "_" + nt + ".jpg"
            image.close()
            os.rename(os.path.join(root,fname), os.path.join(root,newname))
0 Kudos
JaredPilbeam2
MVP Regular Contributor

Thanks a lot! I did put the image.close() line in at one point. But, I didn't dedent it as you have. I also never dedented os.rename()

0 Kudos