照片
Google Takeout 照片 JSON 合并教程:修复导出后日期错误
Google Takeout 把照片日期存放在单独的 JSON 文件里。四款免费工具可以把它们合并回照片:每款工具修复什么、具体命令,以及如何检查结果。
其他语言版本: العربيةবাংলাDeutschespañolfrançaisગુજરાતીहिन्दीIndonesiaitaliano日本語ಕನ್ನಡ한국어EnglishमराठीpolskiportuguêsрусскийKiswahiliதமிழ்తెలుగుไทยTürkçeукраїнськаاردوTiếng Việt
你用 Google Takeout 下载了自己的 Google 相册。现在几千张照片旁边躺着几千个 .json 文件,看图软件还说一张 2019 年的照片是昨天拍的。解决办法是做一次 Google Takeout 照片 JSON 合并:工具从 JSON 文件中读取拍摄日期并写回照片,这样所有应用都能重新显示正确的日期。
本指南解释 JSON 文件为什么存在、合并为什么有时会失败,以及四款免费工具如何完成合并。你会看到每款工具的具体命令、它改的是哪个日期,以及在删除任何东西之前检查结果的方法。
为什么照片会附带 JSON 文件
Takeout 为每张照片提供两个文件:图片本身,例如 IMG_1234.jpg,以及一个包含原始日期、GPS 坐标、描述和所属相册的 JSON 文件。一篇导出指南描述了典型的第一印象:一张 2019 年的照片显示日期为“昨天”,没有位置也没有相册,但其实什么都没丢。这些信息都在 JSON 文件里(PixelUnion)。伊利诺伊理工学院对“为什么导出的文件比相册里的照片多”给出了同样的解释(Illinois Tech)。
照片文件和 JSON 文件的内容可能不一致。google-photos-exif 的作者注意到,如果你在 Google 相册里修改了日期,图片内部的元数据并不会更新:新日期只存在于 JSON 文件中。有些图片,往往是别人分享给你的,内部根本没有日期(google-photos-exif)。gphotos-takeout-repair 的 README 揭示了问题的另一半:在解压后的导出文件中,照片、它的编辑版本和 JSON 文件的创建日期都显示为 Takeout 的导出日期(gphotos-takeout-repair)。
所以,只读取照片文件的应用要么看不到日期,要么看到的是你导出的那一天。正确的日期在 JSON 文件里,合并就是把它放回去。
导致合并失败的三个原因
每个合并工具都必须为每张照片找到正确的 JSON 文件。Takeout 的三个细节让这件事变得更难。
- 照片和它的 JSON 文件可能在不同的 zip 包里。 Ente 的迁移常见问题举了一个例子:
flower.jpeg在一个 zip 里,flower.json在另一个 zip 里,两者因此无法匹配(Ente)。Porte 的 README 也把同样的情况列为已知限制:如果元数据文件和图片不在同一个压缩包里,它就找不到(Porte)。 - JSON 文件的命名不统一。 对于
IMG123.jpg,你可能得到IMG123.jpg.json,也可能只是IMG123.json,而且有些文件夹里有找不到对应图片的 JSON 文件(google-photos-exif)。 - 编辑过的照片会导出两份。 Takeout 把原图和编辑后的副本作为哈希值不同的两个文件导出,所以按哈希比较的重复文件查找工具不会把它们标出来(Ente)。编辑后的文件带有
-edited后缀,比如IMG_0001-edited.jpg旁边是IMG_0001.jpg(gphotos-takeout-repair)。
第一个问题的解决办法对所有工具都一样:下载所有 zip 包,然后把它们全部解压到同一个上级文件夹中,子文件夹保持原样(Ente)。如果两个 zip 包里有同名文件夹,要合并文件夹的内容,而不是用一个替换另一个(google-photos-exif)。
伊利诺伊理工学院关于下载的一个提示:让 Takeout 窗口保持在最前面。如果你把它最小化或在其他窗口工作,下载会在 15 分钟后失败,因为 Google 会要求你重新登录(Illinois Tech)。
四款免费的 Google Takeout JSON 合并工具及各自修复的日期
一张照片有两种日期。EXIF 日期(DateTimeOriginal)存储在图片内部,无论传到哪个应用或服务都会跟着它走。文件日期(修改日期或创建日期)属于文件系统,很容易丢失:gpth 的 README 提醒,在 Android 手机上移动文件通常会把它重置(gpth)。选择工具之前,先确认它写入的是哪一种。
下面每条命令中,第一个文件夹是解压后的 Takeout,第二个是一个新的空输出文件夹。
Porte:把日期和位置写进照片
Porte 把相应 JSON 文件中的时间戳和地理位置复制到图片的 EXIF 数据中,不会重新压缩图片。如果找不到日期,它会尝试从文件名中读取,并采用找到的最早日期,以免把文件修改日期当成拍摄日期。它把文件复制到输出文件夹而不是原地修改,把处理失败的文件放进单独的文件夹,并保存一份日志。它不保留相册数据。你可以从项目的发布页面下载现成的程序(Porte):
porte srcpath destpath
google-photos-exif:补上缺失的 EXIF 日期
这个 Node.js 工具从每个 JSON 文件中读取 photoTakenTime。它会设置文件的修改日期,并且只在照片还没有 DateTimeOriginal 时才写入它。无法处理的文件会放进错误文件夹(google-photos-exif)。PixelUnion 的作者用过它,并表示它大约二十分钟就处理完了整个照片库(PixelUnion)。
yarn start --inputDir ~/takeout --outputDir ~/output --errorDir ~/error
gpth:整理到一个文件夹或按月份分类,然后设置文件日期
Google Photos Takeout Helper 是交互式的:运行后回答它提出的问题即可。它把所有照片收集到一个文件夹,或者使用 --divide-to-dates 选项按月份分到不同文件夹,并设置文件的最后修改日期。把 JSON 数据写回 EXIF 仍在它的待办清单上,所以它的 README 额外提供了一条 exiftool 命令,为没有 EXIF 日期的照片把文件日期复制到 EXIF 日期中。在再次动这些文件之前先运行这条命令。注意 gpth 默认是移动文件,所以请保留原始 zip 包(gpth)。
exiftool -overwrite_original -r -if 'not defined DateTimeOriginal' -P "-AllDates<FileModifyDate" "your/output/folder/ALL_PHOTOS/"
gphotos-takeout-repair:去掉 JSON 文件和编辑过的重复照片
这个工具把照片复制到新文件夹,保持文件夹结构,并根据 JSON 文件中的 photoTakenTime 设置每个文件的创建日期。如果存在 -edited 副本,它会保留这个版本(通常是最好的那一个),舍弃原图,所以输出中既没有 JSON 文件也没有编辑过的重复照片(gphotos-takeout-repair)。用 npm install -g gphotos-takeout-repair 安装,然后运行:
gphotos-takeout-repair --src ./unzipped-takeout-dir --dest ./output-dir
如果你希望每张照片的日期都写在图片内部,Porte 会直接写入。用另外三款工具的话,事后要按下面的方法检查 EXIF 日期。
检查日期是否真的写进了照片
不要相信文件管理器里的“修改日期”一栏,要检查元数据本身。
- 不用额外软件: 右键点击一张照片,在 Mac 上选择“显示简介”,在 Windows 上选择“属性”。合并成功后,你应该能看到正确的拍摄日期、GPS 坐标(如果照片原本有的话)以及相机型号(如果有记录)(PixelUnion)。
- 检查整个文件夹: ExifTool 可以列出一个文件夹中每张 JPG 的
DateTimeOriginal标签。下面这行命令基于其文档中的一个示例(ExifTool):
exiftool -DateTimeOriginal -S -s -ext jpg .
如果某行是空的,或者显示的是你导出那一周的日期,说明那张照片没有合并成功。这时去看工具的错误或失败文件夹,并检查对应的 JSON 文件是否来自另一个 zip 包。
- 比较数量。 输出文件夹加上错误文件夹中的照片和视频数量,应该和解压后的 Takeout 大致相同;如果你的工具会去掉编辑过的重复照片,则要减去这些。
一键式替代方案
如果你不想用命令行,也可以用桌面应用完成同样的工作。PHOTOK 是 Pacix Labs 的产品。根据其页面介绍,它会读取 Google 散落各处的 .json 文件,把真实的日期和地点放回去,然后把照片整理到“年 / 月 / 地点”文件夹中,并把完全相同的重复照片单独放到一边。它支持 Windows 10 和 11 以及搭载 Apple 芯片的 Mac,不上传任何内容,也从不删除文件。预览版免费,完整版一次性付费 €49(PHOTOK)。
无论你选择哪条路,是上面的免费工具还是应用,规则都一样:在副本上操作,抽查样本,保留 zip 包。
检查清单
- 下载所有 zip 包,并在第二块硬盘上保留一份副本。
- 把所有 zip 解压到同一个上级文件夹,保留子文件夹,合并同名文件夹。
- 选择一款工具,并弄清它写入的是哪个日期:EXIF 日期、文件日期,还是两者都写。
- 在副本上运行,输出到新的文件夹。
- 抽查不同年份照片的
DateTimeOriginal,并查看错误文件夹。 - 决定如何处理
-edited副本。 - 只有在检查完毕并有了第二份备份之后,才删除 JSON 文件和 zip 包。
常见问题
为什么 Google Takeout 导出的照片旁边会有 JSON 文件?
Google 把它掌握的每张照片的拍摄日期、位置、描述和相册信息保存在照片旁边单独的 .json 文件里。照片文件本身不一定包含同样的信息,例如你在 Google 相册里修改过日期的情况。
可以删除这些 JSON 文件吗?
只有在日期和地点已经写进照片、并且你抽查过一部分之后才可以。在那之前,JSON 文件是唯一保存 Google 所记录的照片日期和位置的地方。
合并工具修复的是哪个日期?
取决于工具。有些把日期写进照片的 EXIF 元数据(DateTimeOriginal),它会随文件一起走;有些只设置文件的修改日期或创建日期,而某些复制方式会把它重置。选择之前请先读工具的 README。
为什么合并后有些照片的日期还是不对?
通常是照片和它的 JSON 文件在不同的 zip 包里,从未被放到一起,或者 JSON 文件的名字和照片不一样。把所有 zip 解压到同一个文件夹,在一份新的副本上重新运行工具,并查看工具的错误或失败文件夹。
原始的 zip 文件需要保留吗?
需要,直到合并后的照片库检查完毕并且你有了另一份备份。有些工具是移动文件而不是复制文件,zip 包是你重新开始的唯一途径。
来源
- Ente: Google Photos migration FAQ (split zips, wrong dates, duplicates)
- PixelUnion: how to export your Google Photos library without losing the metadata
- Illinois Tech: use Google Takeout to export Google Photos
- google-photos-exif (GitHub README)
- Porte: fixing and organizing a Google Takeout photos export (GitHub README)
- Google Photos Takeout Helper, gpth (GitHub README)
- gphotos-takeout-repair 1.4.2 (README)
- ExifTool documentation