Script Python pour renommer les fichiers selon la date EXIF 'Created on'

Ce script renommera les fichiers dans un répertoire spécifié en fonction de la date EXIF “Created on”.

Comment utiliser

exifrename_usage.sh
# Pour juste imprimer ce qui serait fait, sans réellement renommer les fichiers :
python exifrename.py <directory> --dry-run
# Pour renommer les fichiers :
python exifrename.py <directory>

Exemple :

exifrename_example.txt
Renaming: IMG_5198.JPG -> campchyoca/14/2021-07-03_07-47-04-IMG_5198.JPG

Code source complet

exifrename.py
#!/usr/bin/env python3
import os
import argparse
from pathlib import Path
from PIL import Image, ExifTags
from datetime import datetime

def get_exif_creation_date(file_path):
    """Récupérer la date de création EXIF d'un fichier image."""
    try:
        with Image.open(file_path) as img:
            exif = img._getexif()
            if exif is not None:
                for tag, value in exif.items():
                    decoded_tag = ExifTags.TAGS.get(tag, tag)
                    if decoded_tag == "DateTimeOriginal":
                        return value
    except Exception as e:
        print(f"Error reading EXIF data from {file_path}: {e}")
    return None

def format_filename(date_string, original_name):
    """Formater le nom de fichier avec la date et le nom original."""
    try:
        date_object = datetime.strptime(date_string, "%Y:%m:%d %H:%M:%S")
        formatted_date = date_object.strftime("%Y-%m-%d_%H-%M-%S")
        return f"{formatted_date}-{original_name}"
    except ValueError:
        print(f"Invalid date format for {original_name}: {date_string}")
        return None

def ensure_unique_filename(directory, filename):
    """S'assurer que le nom de fichier est unique dans le répertoire en ajoutant un compteur si nécessaire."""
    base, ext = os.path.splitext(filename)
    counter = 1
    while (directory / filename).exists():
        filename = f"{base}.{counter}{ext}"
        counter += 1
    return filename

def exif_rename_files(directory, dry_run, recursive=False):
    """Renommer les fichiers dans le répertoire spécifié en fonction de leur date de création EXIF."""
    # Traiter les fichiers dans le répertoire courant
    for file in directory.iterdir():
        if file.is_file():
            exif_date = get_exif_creation_date(file)
            if exif_date:
                new_name = format_filename(exif_date, file.name)
                if new_name:
                    # Vérifier si la date formatée est déjà dans le nom de fichier
                    date_object = datetime.strptime(exif_date, "%Y:%m:%d %H:%M:%S")
                    formatted_date = date_object.strftime("%Y-%m-%d_%H-%M-%S")
                    if formatted_date in file.name:
                        print(f"Skipping: {file} (already contains EXIF date)")
                        continue

                    unique_name = ensure_unique_filename(directory, new_name)
                    new_path = directory / unique_name
                    if dry_run:
                        print(f"Would rename: {file} -> {new_path}")
                    else:
                        print(f"Renaming: {file} -> {new_path}")
                        file.rename(new_path)

    # Traiter les sous-répertoires si l'option récursive est activée
    if recursive:
        for subdir in directory.iterdir():
            if subdir.is_dir():
                print(f"Processing subdirectory: {subdir}")
                exif_rename_files(subdir, dry_run, recursive)

def main():
    parser = argparse.ArgumentParser(description="Rename files based on EXIF creation date.")
    parser.add_argument("directory", type=Path, help="Directory containing files to rename.")
    parser.add_argument("--dry-run", action="store_true", help="Show what would be done without making changes.")
    parser.add_argument("-r", "--recursive", action="store_true", help="Process subdirectories recursively.")
    args = parser.parse_args()

    if not args.directory.is_dir():
        print(f"Error: {args.directory} is not a valid directory.")
        return

    exif_rename_files(args.directory, args.dry_run, args.recursive)

if __name__ == "__main__":
    main()
example.txt

Check out similar posts by category: Python