Effacer les jpgs des RAW+jpg en Python
Par Darko Stankovski, 17/01/2024 (Mise à jour 14/05/2026) — Débutant
10 ans après avoir proposé ce même article illustré d'un code Bash, il est temps de proposer une version plus accessible en Python.
Reprenons le contexte : vous photographiez en RAW+jpg et souhaitez supprimer la version jpg (car après tout le fichier jpg généré à partir du RAW sera meilleur). Vous pourriez simplement supprimer tous les jpgs mais vous courrez le risque de supprimer une photo qui n'a été prise qu'en jpgs. Pour rappel, c'était ce qui pouvait arriver avec mon vieux Canon G11.
Il nous faudra donc écrire un petit programme qui parcourt le répertoire des fichiers photo et pour chaque fichier RAW efface le jpg équivalent.
Le problème
Pour comprendre correctement un problème, une petite explication sur le comportement de certains appareils photos et le contenu de sa carte mémoire s'impose.
Les photographes privilégient le format RAW, image brute qui contient toutes les informations pour être corrigée mais qui nécessite un peu de travail après la prise de vue. Les autres se contentent du format jpg, image traitée par l'appareil photo et directement exploitable.
Lors d’une prise de vue en RAW+jpg, l’appareil enregistre sur la carte mémoire deux photos (une en RAW, l’autre en jpg). Les deux photos ont le même nom (disons IMG_0034) mais avec une extension différente. Nous aurons donc, pour un appareil Canon, IMG_0034.CR2 pour la photo format RAW et IMG_OO34.JPG pour la photo au format jpg. Une photo prise uniquement en jpg n’existera qu’en une seule version, disons IMG_0035.JPG.
Nous souhaitons donc supprimer les fichiers .jpg ayant le même nom qu'un fichier RAW
Le principe du programme
Un programme devra donc explorer un répertoire (dossier) prédéfini et, pour chaque photo RAW, déterminer si un fichier portant le même nom avec l'extension .JPG existe et si oui, le supprimer.
Ce programme va donc s'inscrire dans un workflow où vous déchargez toujours votre carte mémoire dans un même répertoire de travail.
Un programme de 6 lignes
En Python, le programme peut être aussi simple que ce programme de 6 lignes presque prêt à l'emploi :
from pathlib import Path
work_dir = '.'
photodir = Path('.').resolve()
for file in photodir.glob('*.CR2'):
jpg_name = file.with_suffix(".JPG")
jpg_name.unlink(missing_ok=True)
Si vous vous ne voulez pas vous prendre la tête, vous pouvez recopier ce code et modifier la ligne 3 avec le chemin vers votre répertoire de travail. Ici, il utilise le répertoire courant.
Explications
Ce programme utilise la bibliothèque pathlib qui me permet de travailler sur les chemins de manière moderne. Cette bibliothèque fait parti de la distribution standard mais doit tout de même être importée.
Après avoir défini ligne 3 une variable pour indiquer le répertoire de travail (ici, le répertoire courant) afin que chacun puisse facilement l'adapter, je construis le chemin vers ce répertoire (ligne 5).
Sur la ligne 7, j'utilise la méthode .glob() qui me permet d'utiliser les glob afin de filtrer les fichiers du répertoire et ne retenir que ceux avec l'extension .CR2. Cette méthode me retourne un générateur sur lequel je vais devoir itérer sur la même ligne. Parfait, c'est ce que je veux faire.
Le générateur me retourne, à chaque itération, un objet de type Path. Ligne 5, la méthode .with_suffix() de l'objet Path retourne un objet Path où le nom de l'extension a été remplacé par celle en argument. Ce nouvel objet Path, jpg_name, est abstrait : il représente un chemin qui n'existe pas forcément.
la méthode .unlink(), ligne 6, supprime le fichier. Si le fichier n'existe pas (cas où on n'a une photo que en RAW), cette méthode lève une exception mais l'argument missing_ok=True permet d'ignorer cette exception (cela correspond à un rm -f en shell).
Et voilà, c'est tout et suffisant pour un usage basique. Sachez cependant qu'en cas d'erreur du nom de répertoire comme référencer un répertoire qui n'existe pas, le programme ne plantera pas et se terminera sans avoir rien fait.
De ce fait, il fait le job pour un débutant mais est limité. Nous pouvons l'améliorer afin d'aller plus loin si nécessaire.
Isolons dans une fonction
Ce code a sa place dans une fonction qui pourra être paramétrée avec, au moins, le nom du chemin où sont les photos. Le programme équivalent utilisant une fonction devient :
from pathlib import Path
def remove_jpg_from_raw(dir_path:Path|str, missing_ok:bool=True):
photodir = Path(dir_path).resolve()
for file in photodir.glob('*.CR2'):
jpg_name = file.with_suffix(".JPG")
jpg_name.unlink(missing_ok=missing_ok)
if __name__ == "__main__":
work_dir = '.'
remove_jpg_from_raw(work_dir)
Dans cette fonction, missing_ok est aussi un paramètre mais optionnel. Vous pouvez choisir que ce n'est pas ok.
Un script utilisable et une base pour du plus robuste
Ce dernier script, vous pouvez l'utiliser directement (en adaptant le chemin dans le __main__). Mais vous pouvez écrire un script plus robuste qui validera le répertoire avant d'appeler la fonction. Vous pouvez même voir comment obtenir le chemin vers le répertoire de travail. Ce peut être une constante ou un paramètre du script.
D'autres évolutions sont à imaginer. Vous pouvez faire évoluer cette fonction en lui ajoutant, en paramètres optionnels, les extension à utiliser pour les fichiers RAW et jpg. Modifier la suppression pour compter le nombre de fichiers parcourus et supprimés et les retourner, ce qui peut être intéressant pour le suivi.
Vous pouvez retrouver ce code sur mon projet GitHub dans le module photocleanup.py.