Takeout JSON

Corriger les dates Google Takeout avec exiftool : guide honnête

La commande exiftool qui copie dates et GPS des fichiers .json de Takeout dans vos photos, les cas où elle échoue, et quand une application devient plus simple.

exiftool est gratuit, tourne partout et peut corriger un export Google Takeout. La plupart des guides donnent une commande et s'arrêtent là. Cette commande fonctionne pour environ quatre photos sur cinq. Ce guide vous dit ce qui arrive à la cinquième.

Installer exiftool

Sur Mac, brew install exiftool. Sur Debian ou Ubuntu, sudo apt install libimage-exiftool-perl. Sur Fedora, sudo dnf install perl-Image-ExifTool. Sous Windows, téléchargez le zip sur exiftool.org, décompressez-le et renommez exiftool(-k).exe en exiftool.exe. Ouvrez ensuite un terminal dans le dossier qui contient votre dossier Takeout décompressé.

Travaillez sur une copie la première fois. exiftool écrit dans vos fichiers.

La commande

Chaque photo a un fichier JSON à côté d'elle, IMG_2034.JPG.supplemental-metadata.json dans les exports depuis 2024, IMG_2034.JPG.json dans les plus anciens. Le champ photoTakenTime.timestamp du JSON est la vraie date, en secondes depuis 1970. Cette commande la copie dans la photo :

exiftool -r -d %s -tagsfromfile "%d/%F.supplemental-metadata.json" \
  "-DateTimeOriginal<PhotoTakenTimeTimestamp" \
  "-CreateDate<PhotoTakenTimeTimestamp" \
  "-FileModifyDate<PhotoTakenTimeTimestamp" \
  -ext jpg -ext jpeg -ext png -ext heic -ext gif \
  -overwrite_original -progress "Takeout/Google Photos"

Morceau par morceau : -r parcourt les sous-dossiers. -d %s indique que la date lue est un nombre de secondes. -tagsfromfile désigne le JSON avec %d (le dossier de la photo) et %F (son nom avec extension). Les trois lignes avec < copient l'horodatage dans la date EXIF, la date de création EXIF et la date de modification du fichier. -overwrite_original évite qu'exiftool laisse une copie _original de chaque fichier.

Pour un export ancien, relancez avec "%d/%F.json". Les fichiers déjà datés lors de la première passe sont simplement réécrits avec la même valeur.

Pour ajouter le GPS dans la même passe, quatre lignes de plus :

  "-GPSLatitude<GeoDataLatitude" "-GPSLatitudeRef<GeoDataLatitude" \
  "-GPSLongitude<GeoDataLongitude" "-GPSLongitudeRef<GeoDataLongitude" \

Google écrit 0.0 pour les photos sans lieu, donc entourez cela d'un -if '$GeoDataLatitude ne 0', sinon vous enverrez quelques centaines de photos dans l'Atlantique. Voir retrouver la localisation GPS.

À la fin, exiftool affiche combien de fichiers il a mis à jour et combien il a ignorés. Les ignorés, c'est là que passe la soirée.

Là où ça casse

Les noms de JSON tronqués. Google coupe les noms trop longs à environ 46 caractères. PXL_20230812_193044123.RAW-01.COVER.jpg reçoit un JSON nommé PXL_20230812_193044123.RAW-01.COVER.supplemen.json ou plus court. Le motif %F ne correspond jamais. Les noms d'appareil longs, les noms WhatsApp et tout nom contenant une description sont touchés. Il faut lister ce qui reste et l'apparier à la main ou avec un script.

Les doublons avec (1). Si vous avez envoyé deux fois le même nom, la photo s'appelle IMG_1234(1).jpg mais le JSON IMG_1234.jpg(1).json. La parenthèse s'est déplacée. Un renommage des JSON avant la commande principale règle cela :

for j in "Takeout/Google Photos"/*/*"("*").json"; do
  mv "$j" "$(echo "$j" | sed -E 's/\.([a-zA-Z0-9]+)\(([0-9]+)\)(\.supplemental-metadata)?\.json$/(\2).\1\3.json/')"
done

Les copies modifiées. IMG_1234-modifié.jpg (ou -edited) n'a pas de JSON à elle. Elle partage celui de l'original. Une fois les originaux traités, copiez depuis eux :

for f in "Takeout/Google Photos"/*/*-edited.*; do
  exiftool -tagsfromfile "${f/-edited/}" -AllDates -GPS:all -overwrite_original "$f"
done

Les vidéos. Les MP4 et MOV n'utilisent pas l'EXIF. Leurs dates sont dans le conteneur QuickTime, sous d'autres balises, lues en UTC :

exiftool -r -d %s -api QuickTimeUTC -tagsfromfile "%d/%F.supplemental-metadata.json" \
  "-CreateDate<PhotoTakenTimeTimestamp" "-ModifyDate<PhotoTakenTimeTimestamp" \
  "-TrackCreateDate<PhotoTakenTimeTimestamp" "-MediaCreateDate<PhotoTakenTimeTimestamp" \
  "-FileModifyDate<PhotoTakenTimeTimestamp" \
  -ext mp4 -ext mov -overwrite_original "Takeout/Google Photos"

Les clips de Live Photos n'ont aucun JSON, donc ils restent sans date après tout cela. Il faut une boucle qui copie la date de la photo fixe vers le clip du même nom.

Le piège du fuseau horaire

L'horodatage du JSON est un instant exact en UTC. Le DateTimeOriginal de l'EXIF est une heure murale sans fuseau. exiftool fait le pont avec le fuseau courant de votre ordinateur. Une photo prise à 11h05 à Paris ressort à 11h05 si la machine est réglée sur Paris, et à 05h05 si elle est réglée sur New York.

Réglez le fuseau avant de lancer, pour le lieu où la plupart de vos photos ont été prises :

TZ=Europe/Paris exiftool ...

Les photos de vacances prises dans d'autres fuseaux resteront décalées de quelques heures. Il n'y a pas de solution à partir du JSON seul ; l'EXIF d'origine de l'appareil, s'il a survécu, est le seul témoin de l'heure locale. Ne « corrigez » pas les photos qui ont déjà une bonne date EXIF. Ajoutez -if 'not $DateTimeOriginal' pour les laisser tranquilles.

Est-ce que la soirée en vaut la peine

Pour un export propre de quelques milliers de photos d'appareil, exiftool prend une heure, lecture de ce guide comprise. Prévoyez une soirée pour une vraie bibliothèque avec des images WhatsApp, des captures d'écran, des doublons (1), du HEIC, des vidéos et des Live Photos, et attendez-vous à lancer exiftool -r -if 'not $DateTimeOriginal' -filename plusieurs fois pour voir ce qui reste sans date.

Si vous voulez en plus renommer les fichiers par date, les classer par année et par mois, convertir le HEIC en JPG et garder les paires de Live Photos ensemble, vous enchaînez quatre commandes de plus et une boucle. C'est très bien si cela vous plaît. GooglePhotosTakeoutHelper est un script gratuit qui gère les bizarreries de nommage pour vous, une bonne étape intermédiaire si le terminal ne vous dérange pas mais que vous ne voulez pas écrire le sed vous-même.

L'application

Takeout JSON Metadata Fixer fait toute la liste en une seule exécution, avec une simulation d'abord, sur Windows, Mac et Linux.

Elle associe chaque photo à son JSON, y compris les noms tronqués, les doublons (1) et les copies modifiées, et écrit photoTakenTime et le GPS dans le fichier. Les vidéos reçoivent les balises QuickTime. Les clips de Live Photos héritent de la date de la photo fixe. Les photos sans JSON gardent leur date EXIF, et celles qui n'ont ni l'un ni l'autre reçoivent la date du fichier, donc rien ne ressort sans date.

Les modèles de nom et de dossier sont facultatifs ; « Conserver les noms » et « Conserver mes dossiers » ne fait que les dates. Elle vérifie l'espace disque avant de commencer et fonctionne entièrement hors ligne. Les 1000 premières photos sont gratuites. L'illimité coûte 19,99 USD une fois, ce qui est moins qu'une soirée.

Questions fréquentes

exiftool dit « Warning: No writable tags set from » un JSON. Que signifie ce message ?

Le JSON existe mais n'a pas de photoTakenTime, ou le motif de nom a désigné le mauvais fichier. Ouvrez le .json et vérifiez. Les metadata.json d'album déclenchent aussi ce message et peuvent être ignorés.

Puis-je le lancer sur les zip sans les décompresser ?

Non. exiftool a besoin des fichiers sur le disque. Décompressez d'abord toutes les parties dans un seul dossier.

Écrire l'EXIF modifie-t-il l'image ?

Non. exiftool réécrit le bloc de métadonnées et ne touche pas aux données de l'image. Le fichier peut grossir de quelques centaines d'octets.

Quelle date copier, photoTakenTime ou creationTime ?

photoTakenTime. creationTime est la date d'envoi vers Google, souvent des années plus tard.