Organize your Photos with Python Automation
Do you have huge number of images lying in a single folder? Do you feel the need to organize it but you don’t want to since it’s a very tedious procedure, sometimes even impossible to?
Do you have huge number of images lying in a single folder? Do you feel the need to organize it but you don’t want to since it’s a very tedious procedure, sometimes even impossible to?
Well, you don’t have to worry anymore since Python has come to rescue you!
“What all can I do with it?”
Almost ANYTHING. You can take all the photos and organize it by device Name, Year, Month even Day!
The functionalities are ENDLESS!
“But I don’t even have such data in my images, not even the filenames. How is this possible?”
With the power of EXIF (Exchangeable image file format)
“…What?”
Every time you click an image, some sort of Meta Data gets stored in your image which describes various information regarding the image.
You must’ve seen it in your Phone when you click the “Information” or “i” button. You can see various information like the timestamp, Device Name and for modern devices, GPS as well.
Now, since you understand where we are getting the data from, let’s get started!
Getting the EXIF data
We’ll be using the renowned PIL package to get the EXIF data. The “_getexif()” function returns a dictionary with some numbers as the key and the data as values.
with PIL.Image.open(os.path.join(self.dirname,fname)) as img:
exif = img._getexif()
But we must understand what the not-so-random numbers in the keys mean!
Reading the Data
The makers of EXIF have specifically mentioned keys that describe specific things. For Example:
Key 271 : Manufacturer Name
Key 272 : Device Name
Key 306 : Time Stamp of the Image taken
You can browse all the Keys/Tags here
Extracting and Cleaning these Tags
We need to first, clean those tags, since they might come with escape sequences or extra whitespace.
def preprocess_exif(data):
data = data.strip()
data = data.strip('\x00')
return data# Get Manufacturer's name
manuf = preprocess_exif(exif[271])#Get Device Name
device = preprocess_exif(exif[272])#Get Timestamp
ts = preprocess_exif(exif[306])
Sort Images By Device Name
We are using Python’s OS module to make life easier for us.
First, we need to get all the filenames from the directory
images = os.listdir(dirname)
Now, I’ll speed up things and paste the entire code and explain line-by-line.
def sort_by_device():
for fname in images: #1
with PIL.Image.open(os.path.join(dirname,fname)) as img:
exif = img._getexif()
manuf = preprocess_exif(exif[271]) #2.1
device = preprocess_exif(exif[272]) #2.2
merged = manuf + ' ' + device
if not os.path.isdir(merged): #3
os.mkdir(merged)
shutil.move(os.path.join(dirname, fname), os.path.join(merged,fname)) #4
The initial “for-loop” loops around all the filenames we’ve extracted from the directory. (Check #1)
We get the EXIF data with the same method as mentioned above. (Check #2)
We create a directory with the name of the Device Name if it doesn’t exist. (Check #3)
We use the shutil module to move the files from its source to the destination.
For Sorting By Year
Most of the part remains the same but here we need to parse the Timestamp.
For this we use the DateTime Module From Python
Here’s the code for it
year = datetime.datetime.strptime(date, '%Y:%m:%d').strftime('%Y')
So, all the timestamps are in the same format (yyyy:mm:dd hh:mm:ss), we just parse it to a DateTime object and get the Year. Yeah, I could have done string split too but it specially helps in the case of Months.
month = datetime.datetime.strptime(date, '%Y:%m:%d').strftime('%b')
This returns the string “Jan,Feb” from the parsed object. Cool!
You can know more about the DateTime Module Here
https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior
And DONE! Pretty Sweet Right?
In similar ways we can form any sort of permutations, sort by year, month, day, or the combination of all.
Don’t worry, I’ve tried to include many of these permutations in my Github Repository, go check it out!