I have a large image library of photos I've taken or downloaded over the years. They are from various cameras and sources, many with missing or incomplete Exif metadata.
This is problematic because some image viewing programs and galleries use metadata to sort images into timelines. For example, when I view my library in Dropbox Photos timeline, images with missing Exif date tags are not displayed.
To remedy this, I wrote a Python script to fix the dates in my photo library. It uses gexiv2, which is a wrapper around the Exiv2 photo metadata library.
The scipt will:
- recursively scan a directory tree for jpg and png files
- get each file's creation time
- convert it to a timestamp string
- set Exif.Image.DateTime tag to timestamp
- set Exif.Photo.DateTimeDigitized tag to timestamp
- set Exif.Photo.DateTimeOriginal tag to timestamp
- save file with modified metadata
- set file access and modified times to file creation time
* Note: it does modifications in-place.
The Code:
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/env python | |
# | |
# gexiv2 image Exif date fixer. | |
# Corey Goldberg, 2014 | |
"""Recursively scan a directory tree, fixing dates | |
on all jpg/png image files. | |
Each file's Exif metadata and atime/mtime are all | |
set to the file's ctime. | |
Modifications are done in-place. | |
Requires: gexiv2 | |
""" | |
import os | |
import time | |
# GObject-based wrapper around the Exiv2 library. | |
# sudo apt-get install gir1.2-gexiv2-0.4 | |
from gi.repository import GExiv2 | |
def fix_image_dates(img_path): | |
t = os.path.getctime(img_path) | |
ctime = time.strftime('%Y:%m:%d %H:%M:%S', time.localtime(t)) | |
exif = GExiv2.Metadata(img_path) | |
exif['Exif.Image.DateTime'] = ctime | |
exif['Exif.Photo.DateTimeDigitized'] = ctime | |
exif['Exif.Photo.DateTimeOriginal'] = ctime | |
exif.save_file() | |
os.utime(img_path, (t, t)) | |
if __name__ == '__main__': | |
dir = '.' | |
for root, dirs, file_names in os.walk(dir): | |
for file_name in file_names: | |
if file_name.lower().endswith(('jpg', 'png')): | |
img_path = os.path.join(root, file_name) | |
fix_image_dates(img_path) |
No comments:
Post a Comment