Renommer ses photos en masse… en Python
Ou comment découvrir que des notions en programmation peuvent vous faciliter le quotidien…
Mais on va quand même éviter toute confusion : cet article ne propose pas une solution plus simple que mon précédent article Renommer ses photos en masse avec Exiftool. Ici, je vais vous montrer comment faire plein de choses que Exiftool fait pour vous. Pourquoi réécrire ce que fait Exiftool ? Simplement pour pouvoir faire plus que ce que vous propose ce logiciel.
Cet article est est donc la première étape vers une automatisation de votre gestion de photos.
Cet article n’a pas non plus pour but d’initier un néophyte à la programmation. Je pense avoir rendu les grandes lignes accessibles pour que vous puissiez voir ce que l’on peut faire et peut-être éveiller votre intérêt. Si vous avez déjà des notions, l’exemple ci-dessous n’est pas un exemple complet clef-en-main. L’objectif est de vous montrer que si vous avez la possibilité de donner vous même des instructions à votre ordinateur, vous pourrez adapter l’exécution à votre besoin.
Modernisation
Cet article, initialement écrit en 2017, a été mis à jour en… 2024… Pour utiliser un parcours plus moderne des répertoires. Les méthodes historiques ont donc été remplacées par Pathlib
.
Pourquoi Python ?
Pour donner des instructions à un ordinateur, il faut choisir un langage. Je ne vais pas m’étendre sur les différences entre eux et je vais faire simple : Python est un langage facile à apprendre et à mettre en pratique. Il est disponible sur toutes les plate-formes (Linux, Mac et même Windows). Python dispose d’une forte communauté qui fait vivre le langage et lui apporte de nouvelles fonctionnalités comme celles que nous allons voir. Enfin, ces caractéristiques font de Python le langage aujourd’hui le plus adapté à l’enseignement de la programmation.
Rappel : lister les fichiers en Python
Nous souhaitons récupérer la liste des fichiers du répertoire courant. Pour ce faire, historiquement, en Python, il y avait deux manières : soit en utilisant la fonction listdir ou plus récemment scandir du module os, soit en utilisant la fonction glob du module glob. Cette dernière permet de filtrer les fichiers par des motifs (par exemple uniquement les fichiers avec l’extension CR2).
Néanmoins, ces fonctions peuvent aujourd’hui être considérées comme obsolètes car elles sont peu pratiques à l’usage. Une manière plus moderne est d’utiliser le module pathlib. Celui nous permet de travailler avec des objets représentant des chemins.
Je vais considérer le cas où notre répertoire contient des fichiers image avec plusieurs types d’extension et que vous souhaitez tous les charger. Nous allons filtrer les éléments Cela va être un peu plus complexe (et nous permet d’utiliser les listes en intension 🙂 ) :
from pathlib import Path image_dir = '.' # peut être n'importe quel chemin valide image_ext = ['.jpg', '.jpeg', '.JPG', '.JPEG'] image_files = [f for f in Path(image_dir).resolve().iterdir() if f.suffix in image_ext]
Astuce : si la liste image_ext
est redondante, c’est parce que Python est sensible à la casse. Donc jpg est différent de JPG. Plutôt que de lister tous les cas de figure, le principe est d’uniformiser la casse des chaines à comparer. Vous pouvez donc déclarer une liste d’extensions en minuscules et convertir le résultat du fichier lu par la méthode lower().
from pathlib import Path image_ext = ['.jpg', '.jpeg'] image_files = [f for f in Path(image_dir).resolve().iterdir() if f.suffix.lower() in image_ext]
Rappel : renommer les fichiers en Python
Renommer un fichier en Python se fait avec la fonction rename() du module os. Mais quand nous travaillons avec pathlib, cela se fait avec la méthode rename() de l’objet de type Path en lui fournissant comme argument un objet de type Path.
from pathlib import Path old_path = Path('old_name.txt') new_path = Path('new_name.txt') old_path.rename(new_path)
Rappelez-vous qu’un objet Path représente un chemin vers un fichier (ou répertoire) mais ne signifie pas que ce chemin existe. Le chemin new_path n’existe donc pas à la déclaration. Jusqu’à la ligne 5, le code précédent fonctionne sans erreur même si old_path n’existe pas réellement. Mais à l’appel de la méthode .rename(), le chemin doit exister et le fichier est renommé.
Attention cependant, si un fichier portant le nom tel qu’il sera renommé existe, sur un système Posix (Linux ou Mac), il sera remplacé silencieusement et sous Windows l’exception FileExistsError sera levée. Ci-dessous, nous testerons son existence avant de procéder au changement de nom.
Récupérer la date de prise de vue
Je souhaite renommer mes fichiers photo en fonction de leur date de prise de vue. Celle-ci est contenue dans les données Exif du fichier photo. Pour lire ces données Exif, nous allons utiliser une librairie externe : ExifRead. Le lien explique comment installer cette dépendance.
ExifRead permet de charger toutes les données Exif sous forme d’un dictionnaire. Nous allons pouvoir récupérer la date à l’aide de sa clef, « EXIF DateTimeOriginal« . Cette date, si elle existe, est présente sous la forme d’une chaine de caractère qu’il sera possible de lire afin de créer un objet du type datetime. Le format correspond au motif ‘%Y:%m:%d %H:%M:%S’. Nous allons donc avoir :
from pathlib import Path from datetime import datetime import exifread image_path = 'mon_image.CR2' with open(image_path, 'rb') as my_picture: tags = exifread.process_file(my_picture) try: picture_date = datetime.strptime(str( tags.get('EXIF DateTimeOriginal')), '%Y:%m:%d %H:%M:%S') except ValueError: picture_date = None print(f"No value for {filename}")
Dans cet exemple de code, l’absence de la donnée Exif ou un mauvais format de date est gérée par une exception. Là je vous laisse libre de faire ce que vous voulez. La variable picture_date contient un objet de type datetime qui va nous faciliter la manipulation de la date de prise de vue et notamment la génération du nom de fichier de sortie. Le format que j’utilise est définit par le motif ‘%y%m%d-%H%M%S’. Celui-ci est passé en paramètre à la méthode strftime.
Renommer le fichier
Grâce au code précédent, je peux donc créer le nom du fichier de destination et procéder à la copie pour les fichier dont j’ai pu récupérer une date par les instructions suivantes :
if picture_date: rename_file_name = picture_date.strftime('%y%m%d-%H%M%S') + image_path.suffix rename_path = image_path.with_name(rename_file_name) if not rename_path.exists(): image_path.rename(rename_path) else: print(f"Fichier {rename_path} existe déjà")
Vous avez maintenant de quoi écrire votre propre programme pour renommer vos photos. Je vous propose pour ma part sur mon Github un exemple de mise en œuvre basé sur cet article.
Reste la question de pourquoi tout ça alors que nous avons des logiciels qui le font déjà ? Pour deux raisons présentées dans la partie suivante dans d’autres articles.
Apprenez et développez
L’aspect pédagogique
Même si ce billet n’est pas un cours complet de Python, l’aspect pédagogique est la raison pour laquelle je détaille certaines notions. Nous avons vu comment :
- obtenir la liste des fichiers d’un répertoire et en particulier, comment n’obtenir que certains fichiers
- utiliser une librairie externe
- extraire des informations de ces fichiers et en particulier une métadonnée d’un fichier image
- transformer cette donnée pour un autre usage, ici générer un nom pour renommer le fichier
- effectuer quelques contrôles afin d’éviter les incidents.
Une première brique
Lorsqu’on écrit quelques lignes de code, c’est pour se faciliter la vie. Mais c’est aussi pour pouvoir les réutiliser pour autre chose. Sur la base de ce code, nous avons la possibilité d’exploiter d’autres métadonnées de la prise de vue. Mais nous avons aussi la possibilité d’exploiter cette métadonnée pour autre chose. Et si nous en profitions pour ranger automatiquement ces photos ? Ça va être très intéressant mais… Pour un prochain billet 😉
À propos de... Darko Stankovski
iT guy, photographe et papa 3.0, je vous fais partager mon expérience et découvertes dans ces domaines. Vous pouvez me suivre sur les liens ci-dessous.
3 réponses
[…] mon article précédent, pour renommer nos photos en Python, il était nécessitait d’extraire l’information de la date de prise de vue. Tant que nous […]
[…] vous ai proposé un article sur comment renommer vos photos avec Python. Le code que je vous ai proposé dans l’article et qui est disponible sur mon Github, […]
[…] vous ai proposé plusieurs exemple de scripts comme renommer ses photos en Python ou supprimer les jpgs lorsqu’on photographie en RAW+jpg. Ces scripts traitent le répertoire […]