суббота, 5 октября 2024 г.

Как поменять дату файла в каждой картинке, которую вы скачали с Google Takeout

Ситуация c Google Photo

После скачивания архива картинок из Google Photo через Google Takeout (Google Архиватор) у многих встает проблема, что все файлы с картинками и видео имеют текущую дату создания, а не реальную дату, когда фотка была сделана.

Реальную дату, когда фотка снята можно посмотреть в EXIF полях самого JPG файла. Время будет указано по часовому поясу той локации, где вы находились. Для этого в MacOS кликните два раза на сам файл JPG и когда картинка откроется для просмотра, нажмите кнопку i

Одновременно, если посмотреть json файл, приложенный к данной картинке добрыми программистами Google, то в нем есть дата и время:
  "photoTakenTime": {
    "timestamp": "1540712405",
    "formatted": "28 окт. 2018 г., 07:40:05 UTC"
  },

Однако, эта дата еще и испорчена - она написана в часовом поясе UTC (единое мировое время). И время по UTC тоже есть в EXIF заголовке. (Кстати, для меня загадка почему время не совпадает между EXIF полями в самом JPG файле: 7:39 и 15:40 - разница в 1 минуту)

Получается, чтобы поправить время из JSON файла в UTC надо еще считать и GPS координаты и поменять на нужный часовой пояс. Они там тоже есть:
 "geoData": {
    "latitude": -8.500833300000002,
    "longitude": 114.96166670000001,
    "altitude": 39.0,
    "latitudeSpan": 0.0,
    "longitudeSpan": 0.0
  },

И если вы хотите сделать все даты верными, то это грандиозный труд над 363 гигабайтами архивов, как у меня.

Что делать?


1. За 24 доллара купить MetaData Fixer for Google Takeout. Данная утилита возьмет ваши ZIP файлы, разархивирует и сама поменяет время и затем вторым шагом справит время на соответствующую Тime Zone. Это выглядит для меня странно - зачем два раза обращаться к файлу, если можно было сразу и время поменять и временную зону.




2. За 20 долларов купить Photo Exifer прямо из Apple Store:



3. Есть описание ручного и бесплатного метода. Для этого нужно скачать ExifTool и запустить команду

exiftool -r -d %s -tagsfromfile "%d/%F.json" "-GPSAltitude<GeoDataAltitude" "-GPSLatitude<GeoDataLatitude" "-GPSLatitudeRef<GeoDataLatitude" "-GPSLongitude<GeoDataLongitude" "-GPSLongitudeRef<GeoDataLongitude" "-Keywords<Tags" "-Subject<Tags" "-Caption-Abstract<Description" "-ImageDescription<Description" "-DateTimeOriginal<PhotoTakenTimeTimestamp" -ext "*" -overwrite_original -progress --ext json <DirToProcess>
или
exiftool -R -d %s -tagsfromfile "%d/%F.json" "-GPSAltitude<geodataaltitude" "-gpslatitude<geodatalatitude"="" "-gpslatituderef<geodatalatitude"="" "-gpslongitude<geodatalongitude"="" "-gpslongituderef<geodatalongitude"="" "-keywords<tags"="" "-subject<tags"="" "-caption-abstract<description"="" "-imagedescription<description"="" "-datetimeoriginal<phototakentimetimestamp"="" "-filecreatedate<phototakentimetimestamp"="" -overwrite_original="" -progress="" -ext="" "*"="" <dirtoprocess="">
4. Можно написать самому программу на Python. Вот что советует ChatGPT

import os
import json
from datetime import datetime
from PIL import Image
from PIL.ExifTags import TAGS

# Укажите путь к папке с изображениями и json файлами
folder_path = '/path/to/folder'

# Функция для обновления EXIF даты изображения
def update_image_date(image_path, creation_date):
    try:
        image = Image.open(image_path)
        # Форматирование даты в подходящий формат
        exif_date = datetime.strptime(creation_date, '%Y-%m-%dT%H:%M:%S.%fZ')
        formatted_date = exif_date.strftime('%Y:%m:%d %H:%M:%S')

        # Получение текущих метаданных EXIF (если есть)
        exif_data = image.getexif()
        exif_data[306] = formatted_date  # Tag 306 - DateTime

        # Сохранение изменений
        image.save(image_path, exif=exif_data)
        print(f'Дата обновлена для {image_path}')
    except Exception as e:
        print(f'Ошибка при обновлении {image_path}: {e}')

# Просмотр всех файлов в папке
for file_name in os.listdir(folder_path):
    if file_name.endswith('.json'):
        json_path = os.path.join(folder_path, file_name)
        
        # Чтение json файла
        with open(json_path, 'r') as json_file:
            data = json.load(json_file)
            if 'photoTakenTime' in data:
                creation_time = data['photoTakenTime']['timestamp']
                
                # Поиск соответствующего изображения
                image_name = file_name.replace('.json', '')
                for extension in ['.jpg', '.jpeg', '.png']:  # Поддерживаемые форматы
                    image_path = os.path.join(folder_path, image_name + extension)
                    if os.path.exists(image_path):
                        update_image_date(image_path, creation_time)
                        break

Важные ссылки:

Формат файла JSON из Google Takeoit описан здесь.
Все опции утилиты ExifTool описаны здесь.
Утилита на Python, которая разделяет фото и видео по двум папкам