Takeout JSON

Corregir fechas de Google Takeout con exiftool: la guía honesta

El comando de exiftool que copia fechas y GPS de los .json de Takeout a tus fotos, dónde falla, y cuándo conviene parar y usar una aplicación con ventana.

exiftool es gratuito, funciona en cualquier sistema y puede arreglar una exportación de Google Takeout. Casi todas las guías te dan un comando y se detienen ahí. Ese comando funciona en cuatro de cada cinco fotos. Esta guía te cuenta qué pasa con la quinta.

Instálalo

En un Mac, brew install exiftool. En Debian o Ubuntu, sudo apt install libimage-exiftool-perl. En Fedora, sudo dnf install perl-Image-ExifTool. En Windows, descarga el zip desde exiftool.org, descomprímelo y renombra exiftool(-k).exe a exiftool.exe. Después abre una terminal en la carpeta que contiene tu carpeta Takeout descomprimida.

Trabaja sobre una copia la primera vez. exiftool escribe dentro de tus archivos.

El comando

Cada foto tiene un JSON al lado: IMG_2034.JPG.supplemental-metadata.json en exportaciones desde 2024, IMG_2034.JPG.json en las anteriores. El campo photoTakenTime.timestamp del JSON es la fecha real, en segundos desde 1970. Esto la copia dentro de la 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 Fotos"

Parte por parte: -r recorre las subcarpetas. -d %s le dice a exiftool que la fecha que lee es un número de segundos. -tagsfromfile nombra el JSON usando %d (la carpeta de la foto) y %F (su nombre con extensión). Las tres líneas con < copian la marca de tiempo a la fecha EXIF, a la fecha de creación EXIF y a la fecha de modificación del archivo. -overwrite_original evita que exiftool deje una copia _original de cada archivo.

Para una exportación antigua, ejecútalo otra vez con "%d/%F.json". Los archivos que ya recibieron fecha en la primera pasada simplemente se reescriben con el mismo valor.

Añade el GPS en la misma pasada con cuatro líneas más, si lo quieres:

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

Google escribe 0.0 en las fotos sin ubicación, así que envuélvelo en -if '$GeoDataLatitude ne 0' o pondrás unos cientos de fotos en medio del Atlántico. Hay más sobre esto en recuperar el GPS de Takeout.

Al terminar, exiftool imprime cuántos archivos actualizó y cuántos se saltó. Los que se saltó son donde se va la tarde.

Dónde falla

Nombres de JSON recortados. Google corta los nombres largos de JSON a unos 46 caracteres. PXL_20230812_193044123.RAW-01.COVER.jpg recibe un JSON llamado PXL_20230812_193044123.RAW-01.COVER.supplemen.json o más corto. El patrón %F nunca coincide. Los nombres largos de cámara, los de WhatsApp y cualquier nombre con descripción caen aquí. Tienes que listar los que sobran y emparejarlos a mano o con un script.

Duplicados con (1). Si subiste dos veces el mismo nombre, la foto es IMG_1234(1).jpg pero el JSON es IMG_1234.jpg(1).json. El paréntesis se movió. Una pasada de renombrado sobre los JSON lo resuelve antes de ejecutar el comando principal:

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

Copias editadas. IMG_1234-edited.jpg no tiene JSON propio. Comparte el del original. Una vez hechos los originales, copia desde ellos:

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

Videos. Los MP4 y MOV no usan EXIF. Guardan sus fechas en el contenedor QuickTime, en etiquetas distintas, y esas etiquetas se leen como 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 Fotos"

Los clips de Live Photo no tienen ningún JSON, así que después de esto siguen sin fecha.

La trampa de la zona horaria

La marca de tiempo del JSON es un instante exacto en UTC. El DateTimeOriginal del EXIF es una hora de reloj sin zona. exiftool salva la diferencia con la zona horaria actual de tu ordenador. Una foto tomada a las 11:05 en Madrid sale como 11:05 si tu equipo está en hora de Madrid, y como 05:05 si está en hora de Bogotá.

Fija la zona antes de ejecutar, la del lugar donde se tomaron la mayoría de tus fotos:

TZ=Europe/Madrid exiftool ...

Las fotos de vacaciones en otras zonas seguirán desplazadas unas horas. No hay forma de evitarlo solo con el JSON; el EXIF de la cámara, si sobrevivió, es el único registro de la hora local. No "arregles" fotos que ya tienen una fecha EXIF buena. Añade -if 'not $DateTimeOriginal' para dejarlas en paz.

¿Merece la pena la tarde?

Para una exportación limpia de unos miles de fotos de cámara, exiftool lleva una hora, contando la lectura de esta guía. Reserva una tarde entera para una biblioteca real con imágenes de WhatsApp, capturas de pantalla, duplicados (1), HEIC, videos y Live Photos, y cuenta con ejecutar exiftool -r -if 'not $DateTimeOriginal' -filename varias veces para ver qué sigue sin fecha.

Si además quieres archivos renombrados por fecha, ordenados en carpetas por año y mes, HEIC convertido a JPG y las parejas de Live Photo juntas, estás encadenando cuatro comandos más y un bucle. Está bien si lo disfrutas. GooglePhotosTakeoutHelper es un script gratuito que resuelve las rarezas de los nombres, y es un buen paso intermedio si te manejas con la terminal pero no quieres escribir el sed tú mismo.

La aplicación

Takeout JSON Metadata Fixer hace toda la lista en una sola ejecución, con simulación previa, en macOS, Windows y Linux.

Empareja cada foto con su JSON, incluidos los nombres recortados, los duplicados (1) y las copias -edited, y escribe photoTakenTime y el GPS en el archivo. Los videos reciben las etiquetas QuickTime. Los clips de Live Photo heredan la fecha de la foto fija. Las fotos sin JSON conservan su fecha EXIF, y las que no tienen ninguna de las dos reciben la fecha del archivo, así que nada sale sin fecha.

Las plantillas de nombres y carpetas son opcionales; "Conservar nombres" y "Conservar mis carpetas" hace solo las fechas. Comprueba el espacio en disco antes de empezar y funciona por completo sin conexión, con la interfaz en español. Las primeras 1000 fotos son gratis. Sin límite cuesta 19,99 USD una sola vez, que es menos que una tarde.

Preguntas frecuentes

exiftool dice "Warning: No writable tags set from" un JSON. ¿Qué significa?

El JSON existe pero no tiene photoTakenTime, o el patrón de nombre coincidió con el archivo equivocado. Abre el .json y compruébalo. Los metadata.json de álbum también provocan este aviso y se pueden ignorar.

¿Puedo ejecutarlo sobre los zips sin descomprimir?

No. exiftool necesita los archivos en disco. Descomprime primero todas las partes en una carpeta, como se explica en descomprimir Google Takeout en varias partes.

¿Escribir el EXIF cambia la imagen?

No. exiftool reescribe el bloque de metadatos y deja intactos los datos de imagen. El archivo puede crecer unos cientos de bytes.

¿Qué fecha copio, photoTakenTime o creationTime?

photoTakenTime. creationTime es cuándo se subió el archivo a Google, a menudo años después.