Takeout JSON
PL

exiftool i daty z Google Takeout: polecenie i jego pułapki

Polecenie exiftool, które kopiuje daty i GPS z plików .json z Takeout do zdjęć, trzy przypadki, które po cichu pomija, i kiedy lepiej użyć aplikacji.

exiftool jest darmowy, działa wszędzie i potrafi naprawić eksport z Google Takeout. Większość poradników podaje jedno polecenie i na tym kończy. To polecenie działa dla mniej więcej czterech zdjęć na pięć. Ten artykuł mówi, co dzieje się z piątym.

Instalacja

Na Macu: brew install exiftool. W Debianie lub Ubuntu: sudo apt install libimage-exiftool-perl. W Fedorze: sudo dnf install perl-Image-ExifTool. W Windows pobierz archiwum zip ze strony exiftool.org, rozpakuj je i zmień nazwę exiftool(-k).exe na exiftool.exe. Potem otwórz terminal w folderze, w którym jest rozpakowany folder Takeout.

Za pierwszym razem pracuj na kopii. exiftool zapisuje dane w twoich plikach.

Polecenie

Każde zdjęcie ma obok plik .json: IMG_2034.JPG.supplemental-metadata.json w eksportach od 2024 roku, IMG_2034.JPG.json w starszych. Pole photoTakenTime.timestamp w pliku .json to prawdziwa data, w sekundach od 1970 roku. To polecenie kopiuje ją do zdjęcia:

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"

Po kolei: -r przechodzi przez podfoldery. -d %s mówi exiftool, że odczytywana data to liczba sekund od 1970 roku. -tagsfromfile wskazuje plik .json za pomocą %d (folder zdjęcia) i %F (nazwa pliku z rozszerzeniem). Trzy wiersze ze znakiem < kopiują znacznik czasu do daty EXIF, daty utworzenia EXIF i daty modyfikacji pliku. -overwrite_original sprawia, że exiftool nie zostawia kopii _original każdego pliku.

Dla starszego eksportu uruchom polecenie jeszcze raz z "%d/%F.json". Pliki, które dostały datę za pierwszym razem, zostaną po prostu zapisane z tą samą wartością.

Jeśli chcesz, dodaj w tym samym przebiegu GPS, czterema kolejnymi wierszami:

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

Google zapisuje 0.0 dla zdjęć bez lokalizacji, więc otocz to warunkiem -if '$GeoDataLatitude ne 0', inaczej kilkaset zdjęć wyląduje na Atlantyku. Więcej na ten temat w artykule restoring GPS from Takeout (po angielsku).

Na koniec exiftool wypisuje, ile plików zaktualizował, a ile pominął. Na te pominięte idzie cały wieczór.

Gdzie to się psuje

Ucięte nazwy plików .json. Google ucina długie nazwy plików .json na około 46 znakach. PXL_20230812_193044123.RAW-01.COVER.jpg dostaje plik .json o nazwie PXL_20230812_193044123.RAW-01.COVER.supplemen.json albo jeszcze krótszej. Wzorzec %F nigdy do niej nie pasuje. Dotyczy to długich nazw z aparatów, nazw z WhatsAppa i wszystkiego, co ma opis w nazwie pliku. Musisz wypisać, co zostało, i dopasować to ręcznie lub skryptem.

Duplikaty z (1). Jeśli dwa razy wysłałeś plik o tej samej nazwie, zdjęcie to IMG_1234(1).jpg, a plik .json to IMG_1234.jpg(1).json. Nawias się przesunął. Pomoże zmiana nazw plików .json przed uruchomieniem głównego polecenia:

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

Edytowane kopie. IMG_1234-edited.jpg nie ma własnego pliku .json. Korzysta z pliku oryginału. Gdy oryginały są gotowe, skopiuj dane z nich:

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

Filmy. Pliki MP4 i MOV nie używają EXIF. Trzymają daty w kontenerze QuickTime, w innych znacznikach, a te znaczniki są odczytywane jako 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"

Klipy Live Photo w ogóle nie mają pliku .json, więc po tym nadal nie mają daty. Pętlę dla nich znajdziesz w artykule The Live Photo pairs article (po angielsku).

Pułapka strefy czasowej

Znacznik czasu w pliku .json to dokładna chwila w UTC. DateTimeOriginal w EXIF to czas zegarowy bez strefy. exiftool łączy jedno z drugim według bieżącej strefy czasowej komputera. Zdjęcie zrobione o 11:05 w Paryżu wyjdzie jako 11:05, jeśli komputer ma ustawiony Paryż, i jako 05:05, jeśli ma ustawiony Nowy Jork.

Przed uruchomieniem ustaw strefę miejsca, w którym zrobiono większość zdjęć:

TZ=Europe/Paris exiftool ...

Zdjęcia z wakacji w innych strefach nadal będą przesunięte o kilka godzin. Samym plikiem .json tego nie obejdziesz; jedynym zapisem czasu lokalnego jest własny EXIF aparatu, jeśli przetrwał. Nie „naprawiaj” zdjęć, które już mają dobrą datę EXIF. Dodaj -if 'not $DateTimeOriginal', żeby je pominąć.

Czy ten wieczór się opłaca

Dla czystego eksportu kilku tysięcy zdjęć z aparatu exiftool zajmie godzinę, łącznie z czytaniem tego artykułu. Na prawdziwą bibliotekę ze zdjęciami z WhatsAppa, zrzutami ekranu, duplikatami (1), HEIC, filmami i Live Photos zarezerwuj wieczór i licz się z tym, że kilka razy uruchomisz exiftool -r -if 'not $DateTimeOriginal' -filename, żeby zobaczyć, co wciąż nie ma daty.

Jeśli chcesz też zmienić nazwy plików według daty, ułożyć je w foldery według roku i miesiąca, zamienić HEIC na JPG i zachować pary Live Photo razem, dokładasz cztery kolejne polecenia i pętlę. To w porządku, jeśli sprawia ci to przyjemność. GooglePhotosTakeoutHelper to darmowy skrypt, który radzi sobie z dziwactwami nazw za ciebie, i dobry krok pośredni, jeśli dobrze czujesz się w terminalu, ale nie chcesz sam pisać polecenia sed.

Aplikacja

Takeout JSON Metadata Fixer robi całą tę listę w jednym przebiegu, najpierw z przebiegiem próbnym, na macOS, Windows i Linux.

Dopasowuje każde zdjęcie do jego pliku .json, także przy uciętych nazwach, duplikatach (1) i kopiach -edited, i zapisuje w pliku photoTakenTime i GPS. Filmy dostają znaczniki QuickTime. Klipy Live Photo dziedziczą datę zdjęcia. Zdjęcia bez pliku .json zachowują datę EXIF, a zdjęcia bez jednego i drugiego dostają datę pliku, więc żadne nie zostaje bez daty.

Szablony nazw i folderów są opcjonalne; jeśli wybierzesz opcje, które zachowują obecne nazwy plików i foldery, aplikacja naprawi tylko daty. Przed startem sprawdza miejsce na dysku i działa całkowicie offline. Pierwsze 1000 zdjęć jest za darmo. Wersja bez limitu kosztuje jednorazowo 19,99 USD, czyli mniej niż jeden wieczór.

Częste pytania

exiftool pisze „Warning: No writable tags set from” przy pliku .json. Co to znaczy?

Plik .json istnieje, ale nie ma photoTakenTime, albo wzorzec nazwy dopasował niewłaściwy plik. Otwórz plik .json i sprawdź. Pliki metadata.json albumów też wywołują ten komunikat i można je zignorować.

Czy mogę uruchomić exiftool na archiwach zip bez rozpakowywania?

Nie. exiftool potrzebuje plików na dysku. Najpierw rozpakuj wszystkie części do jednego folderu, jak opisano w artykule Google Takeout w wielu plikach zip.

Czy zapis EXIF zmienia zdjęcie?

Nie. exiftool zapisuje od nowa blok metadanych, a dane obrazu zostawia nietknięte. Plik może urosnąć o kilkaset bajtów.

Którą datę kopiować: photoTakenTime czy creationTime?

photoTakenTime. creationTime to chwila wysłania pliku do Google, często wiele lat później.