Correggere le date di Google Takeout con exiftool, la guida vera
Il comando exiftool che copia date e GPS dai file .json di Takeout nelle foto, dove si rompe, e quando conviene fermarsi e usare un'app.
exiftool è gratuito, gira ovunque e può sistemare un'esportazione di Google Takeout. La maggior parte delle guide dà un comando e si ferma lì. Quel comando funziona su circa quattro foto su cinque. Questa guida ti dice cosa succede alla quinta.
Installarlo
Su Mac, brew install exiftool. Su Debian o Ubuntu, sudo apt install libimage-exiftool-perl. Su Fedora, sudo dnf install perl-Image-ExifTool. Su Windows, scarica lo zip da exiftool.org, estrailo e rinomina exiftool(-k).exe in exiftool.exe. Poi apri un terminale nella cartella che contiene la cartella Takeout estratta.
La prima volta lavora su una copia. exiftool scrive dentro i tuoi file.
Il comando
Ogni foto ha un file JSON accanto, IMG_2034.JPG.supplemental-metadata.json nelle esportazioni dal 2024 in poi, IMG_2034.JPG.json in quelle più vecchie. Il campo photoTakenTime.timestamp del JSON è la data vera, in secondi dal 1970. Questo la copia nella foto:
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 Foto"
Pezzo per pezzo: -r entra nelle sottocartelle. -d %s dice a exiftool che la data che legge è un numero epoch. -tagsfromfile costruisce il nome del JSON con %d (la cartella della foto) e %F (il nome del file con estensione). Le tre righe con < copiano il timestamp nella data EXIF, nella data di creazione EXIF e nella data di modifica del file. -overwrite_original evita che exiftool lasci una copia _original di ogni file.
Su Windows, nel Prompt dei comandi, scrivi tutto su una riga senza le barre rovesciate. Le cartelle dell'esportazione italiana si chiamano Takeout\Google Foto, con lo spazio, quindi le virgolette servono.
Per un'esportazione vecchia, rilancialo con "%d/%F.json". I file che hanno già ricevuto una data la prima volta vengono semplicemente riscritti con lo stesso valore.
Aggiungi il GPS nello stesso passaggio con quattro righe in più, se lo vuoi:
"-GPSLatitude<GeoDataLatitude" "-GPSLatitudeRef<GeoDataLatitude" \
"-GPSLongitude<GeoDataLongitude" "-GPSLongitudeRef<GeoDataLongitude" \
Google scrive 0.0 per le foto senza posizione, quindi aggiungi -if '$GeoDataLatitude ne 0' o metterai qualche centinaio di foto nell'oceano Atlantico. I dettagli sono in foto di Google Takeout senza posizione.
Alla fine exiftool stampa quanti file ha aggiornato e quanti ne ha saltati. I saltati sono dove se ne va la serata.
Dove si rompe
Nomi dei JSON troncati. Google taglia i nomi lunghi a circa 46 caratteri. PXL_20230812_193044123.RAW-01.COVER.jpg ha un JSON chiamato PXL_20230812_193044123.RAW-01.COVER.supplemen.json o più corto. Lo schema %F non lo trova mai. Nomi lunghi di fotocamera, nomi di WhatsApp e qualunque nome con una descrizione dentro cadono in questo caso. Devi elencare i rimasti e abbinarli a mano o con uno script.
Duplicati con (1). Se hai caricato due volte lo stesso nome, la foto è IMG_1234(1).jpg ma il JSON è IMG_1234.jpg(1).json. La parentesi si è spostata. Un passaggio di rinomina sui JSON, prima del comando principale, sistema la cosa:
for j in "Takeout/Google Foto"/*/*"("*").json"; do
mv "$j" "$(echo "$j" | sed -E 's/\.([a-zA-Z0-9]+)\(([0-9]+)\)(\.supplemental-metadata)?\.json$/(\2).\1\3.json/')"
done
Copie modificate. IMG_1234-edited.jpg non ha un JSON suo. Condivide quello dell'originale. Una volta sistemati gli originali, copia da loro:
for f in "Takeout/Google Foto"/*/*-edited.*; do
exiftool -tagsfromfile "${f/-edited/}" -AllDates -GPS:all -overwrite_original "$f"
done
Video. I file MP4 e MOV non usano l'EXIF. Tengono le date nel contenitore QuickTime, in tag diversi, e quei tag vengono letti come 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 Foto"
Le clip delle Live Photo non hanno nessun JSON, quindi dopo questo restano senza data. L'articolo sulle coppie delle Live Photo (in inglese) ha un ciclo per loro.
La trappola del fuso orario
Il timestamp del JSON è un istante esatto in UTC. DateTimeOriginal dell'EXIF è un'ora da orologio a muro, senza fuso. exiftool colma la differenza con il fuso attuale del computer. Una foto scattata alle 11:05 a Milano esce alle 11:05 se la macchina è impostata sull'Italia, e alle 05:05 se è impostata su New York.
Imposta il fuso prima di lanciare, sul luogo in cui è stata scattata la maggior parte delle foto:
TZ=Europe/Rome exiftool ...
Le foto delle vacanze in altri fusi resteranno spostate di qualche ora. Dal solo JSON non c'è modo di evitarlo; l'EXIF della fotocamera, se è sopravvissuto, è l'unica traccia dell'ora locale. Non "correggere" le foto che hanno già una data EXIF buona: aggiungi -if 'not $DateTimeOriginal' per lasciarle stare.
La serata vale la pena?
Per un'esportazione pulita di qualche migliaio di foto da fotocamera, exiftool porta via un'ora compresa la lettura di questa guida. Metti in conto una serata per una libreria vera, con immagini di WhatsApp, screenshot, duplicati (1), HEIC, video e Live Photo, e aspettati di lanciare exiftool -r -if 'not $DateTimeOriginal' -filename più volte per vedere cosa è rimasto senza data.
Se vuoi anche i file rinominati per data, ordinati in cartelle per anno e mese, gli HEIC convertiti in JPG e le coppie delle Live Photo tenute insieme, stai concatenando altri quattro comandi e un ciclo. Va bene, se ti diverte. GooglePhotosTakeoutHelper è uno script gratuito che gestisce le stranezze dei nomi per te, ed è una buona via di mezzo se ti trovi bene nel terminale ma non vuoi scrivere il sed da solo.
L'app
Takeout JSON Metadata Fixer fa tutta la lista in un'unica esecuzione, con la prova a secco prima, su Windows, Mac e Linux, in italiano.
Abbina ogni foto al suo JSON, compresi i nomi troncati, i duplicati (1) e le copie -edited, e scrive photoTakenTime e il GPS nel file. I video ricevono i tag QuickTime. Le clip delle Live Photo ereditano la data della foto. Le foto senza JSON tengono la loro data EXIF, e quelle senza né l'uno né l'altra prendono la data del file, così nessuna resta senza data.
I modelli di nome e di cartella sono facoltativi; "Mantieni i nomi" e "Mantieni le mie cartelle" fa solo le date. Controlla lo spazio su disco prima di partire e gira completamente offline. Le prime 1000 foto sono gratuite. Senza limiti costa 19,99 USD una volta sola, meno di una serata.
Domande frequenti
exiftool dice "Warning: No writable tags set from" un JSON. Cosa significa?
Il JSON esiste ma non ha photoTakenTime, oppure lo schema del nome ha preso il file sbagliato. Apri il .json e controlla. Anche i metadata.json degli album producono questo avviso e si possono ignorare.
Posso lanciarlo sugli zip senza estrarli?
No. exiftool ha bisogno dei file su disco. Estrai prima tutte le parti in una sola cartella.
Scrivere l'EXIF cambia l'immagine?
No. exiftool riscrive il blocco dei metadati e lascia intatti i dati dell'immagine. Il file può crescere di qualche centinaio di byte.
Quale data copio, photoTakenTime o creationTime?
photoTakenTime. creationTime è il momento del caricamento su Google, spesso anni dopo.