Python Script to Automatically Rename Bulk Images Using EXIF Data

Python Script to Automatically Rename Bulk Images Using EXIF Data

Python Script to Automatically Rename Bulk Images Using EXIF Data

 

Managing large sets of images can quickly become chaotic, especially when filenames like IMG_3412.JPG or DSC00095.JPG offer no useful context. Fortunately, nearly all modern cameras and smartphones embed metadata called EXIF (Exchangeable Image File Format) into each photo. With Python and the Pillow library, we can automate renaming these images using data like the date taken or camera model. This blog post walks you through building a Python script to extract EXIF metadata and rename your images logically and automatically.

1. Understanding EXIF Data in Images

EXIF data contains rich metadata about how and when an image was captured—such as the date taken, camera model, shutter speed, and more. This data is embedded in JPEG and TIFF files and is excellent for organizing photos chronologically or by device. We’ll use the Pillow library to extract this metadata.

Install Pillow if you haven’t already:

pip install Pillow

Here’s a simple snippet to read EXIF data using Pillow:

from PIL import Image
from PIL.ExifTags import TAGS

image_path = 'example.jpg'
image = Image.open(image_path)
exif_data = image._getexif()

if exif_data:
    for tag_id, value in exif_data.items():
        tag = TAGS.get(tag_id, tag_id)
        print(f"{tag:25}: {value}")

This will print out all available EXIF tags for the image, allowing you to identify useful fields like DateTimeOriginal or Model.

2. Extracting Key Metadata Fields

To rename images meaningfully, we’ll focus on two common EXIF fields:

  • DateTimeOriginal – the date and time the photo was taken
  • Model – the camera or device model

Let’s write a helper function to extract specific metadata fields from an image:

def extract_exif_data(image_path):
    try:
        image = Image.open(image_path)
        exif_data = image._getexif()
        if not exif_data:
            return None

        exif = {}
        for tag_id, value in exif_data.items():
            tag = TAGS.get(tag_id, tag_id)
            exif[tag] = value

        date_taken = exif.get('DateTimeOriginal', None)
        camera_model = exif.get('Model', "UnknownModel").replace(' ', '_')

        return date_taken, camera_model
    except Exception as e:
        print(f"Error processing {image_path}: {e}")
        return None

This function will return the date and model or fallback defaults if data is missing.

3. Formatting EXIF Data for Filenames

The DateTimeOriginal field typically looks like '2021:09:01 16:45:30'. To safely use this in filenames, we must format it into something like 2021-09-01_16-45-30.

def safe_filename_from_exif(date_str, model):
    if not date_str:
        return f"{model}_unknown_date"

    safe_date = date_str.replace(":", "-").replace(" ", "_")
    return f"{safe_date}_{model}"

This makes the timestamp filename safe for most operating systems and improves readability when sorting files.

4. Renaming Images in Bulk

With our helper functions in place, we can now rename all images in a folder based on their EXIF data. We’ll iterate through the directory, extract data, and rename each JPEG.

import os

def rename_images_in_folder(folder_path):
    for filename in os.listdir(folder_path):
        if filename.lower().endswith(('.jpg', '.jpeg')):
            full_path = os.path.join(folder_path, filename)
            exif = extract_exif_data(full_path)
            if exif:
                date_taken, model = exif
                new_filename = safe_filename_from_exif(date_taken, model) + ".jpg"
                new_path = os.path.join(folder_path, new_filename)
                try:
                    os.rename(full_path, new_path)
                    print(f"Renamed: {filename} -> {new_filename}")
                except Exception as e:
                    print(f"Failed to rename {filename}: {e}")

This function gracefully handles errors. You can run it like so:

rename_images_in_folder('/path/to/your/photos')

5. Best Practices and Performance Tips

Here are some recommendations to ensure your script performs reliably:

  • Backup your folder – Always back up original files before batch-renaming them.
  • Use unique filenames – Consider adding a hash or sequence number to avoid overwriting files with duplicate EXIF timestamps.
  • Avoid non-JPEG formats – EXIF is mostly standardized in JPEG. PNG and others may lack metadata or use different standards.
  • Optimize for large folders – If processing thousands of images, consider multiprocessing or batching.

For example, you could add a fallback timestamp using file creation time if EXIF is unavailable using os.path.getctime().

Conclusion

By leveraging EXIF data and Python’s powerful image processing libraries, we’ve built a script that intelligently renames images in bulk. This improves photo organization, readability, and archival value—whether you’re a professional photographer or just digitizing old albums. The key takeaway is how easily metadata can be extracted and repurposed to automate repetitive tasks while maintaining context-rich filenames.

Happy scripting!

 

Useful links: