从Google相册迁移到LibrePhotos:数据导入与元信息保留全攻略

从Google相册迁移到LibrePhotos:数据导入与元信息保留全攻略

【免费下载链接】librephotos A self-hosted open source photo management service. This is the repository of the backend. 【免费下载链接】librephotos 项目地址: https://gitcode.com/GitHub_Trending/li/librephotos

引言:告别数据围墙,拥抱自托管照片管理

你是否正受困于Google相册的存储空间限制?担心隐私数据被商业化利用?作为一款开源自托管照片管理系统,LibrePhotos提供了完整的本地数据控制权解决方案。本指南将系统讲解从Google相册迁移到LibrePhotos的全流程,特别聚焦于无损数据迁移关键元信息保留两大核心痛点,确保你的照片库在迁移过程中保持完整的时间线、位置信息和个性化标签。

读完本文后,你将掌握:

  • Google相册数据完整导出的最佳实践
  • LibrePhotos环境的正确配置方法
  • 照片文件与元数据的批量导入技巧
  • EXIF数据与扩展元信息的验证与修复
  • 迁移后的数据一致性检查方案

一、迁移前准备:Google相册数据导出全流程

1.1 Google Takeout完整备份

Google相册的数据导出功能通过Google Takeout实现,为确保迁移质量,需遵循以下导出规范:

选项推荐配置注意事项
数据范围仅选择"Google相册"避免包含其他服务数据,减少处理复杂度
相册格式原始文件 + 元数据确保勾选"包括所有照片和视频"
导出格式ZIP选择最大2GB分卷,避免单个文件过大
元数据选项勾选"导出元数据"将生成JSON格式的补充元信息
交付方式电子邮件下载链接大型相册建议分批次导出

操作步骤

  1. 访问Google Takeout并登录
  2. 取消全选,仅保留"Google相册"
  3. 点击"所有相册数据已包含",可选择特定相册
  4. 滚动至页面底部,点击"下一步"
  5. 选择"发送下载链接",文件类型选"ZIP",大小选"2GB"
  6. 点击"创建导出",等待Google处理(大型相册可能需要数小时)

1.2 导出文件结构解析

Google Takeout导出的相册数据包含两种关键文件类型,理解其结构是成功迁移的基础:

Takeout/
└── Google Photos/
    ├── 2023-01/                  # 按日期组织的媒体文件目录
    │   ├── IMG_1234.jpg          # 原始照片文件
    │   ├── IMG_1234.jpg.json     # 对应照片的元数据JSON
    │   ├── VID_5678.mp4          # 视频文件
    │   └── VID_5678.mp4.json     # 视频元数据JSON
    └── 相册名/                   # 按相册名称组织的媒体文件
        ├── DSC_9012.JPG
        └── DSC_9012.JPG.json

JSON元数据关键字段说明

  • title:照片标题
  • description:照片描述
  • creationTime:拍摄时间戳
  • geoData:地理位置信息(经纬度)
  • people:人物标签
  • albums:所属相册信息

二、LibrePhotos环境准备与配置优化

2.1 系统环境要求

在开始迁移前,请确保你的LibrePhotos服务器满足以下最低配置:

组件最低要求推荐配置
CPU双核处理器四核及以上,支持AVX指令集
内存4GB RAM8GB RAM(处理面部识别需16GB+)
存储至少20GB可用空间SSD存储,容量为照片库1.5倍
操作系统Ubuntu 20.04+Ubuntu 22.04 LTS
Python版本3.8+3.10+

2.2 关键配置文件优化

LibrePhotos的行为主要通过settings目录下的配置文件控制。对于迁移任务,需特别关注以下配置项:

# librephotos/settings/production.py
# 照片扫描根目录配置(迁移核心)
SCAN_DIRECTORY = "/data/photos/google-import"  # 设置为Google Takeout解压目录

# 元数据处理配置
SAVE_METADATA_TO_DISK = True  # 启用元数据写入功能
SAVE_METADATA_USE_SIDECAR = True  # 使用XMP侧栏文件保存元数据

# 性能优化配置(大型相册必备)
THUMBNAIL_SIZE = [512, 1024]  # 减小缩略图尺寸加速处理
PARALLEL_SCAN = True  # 启用并行扫描
MAX_SCAN_THREADS = 4  # 根据CPU核心数调整

配置修改方法

# 编辑配置文件
nano /data/web/disk1/git_repo/GitHub_Trending/li/librephotos/librephotos/settings/production.py

# 重启LibrePhotos服务使配置生效
sudo systemctl restart librephotos

三、数据导入实战:从文件系统到LibrePhotos

3.1 迁移文件组织策略

Google Takeout导出的文件结构需要进行预处理,以适应LibrePhotos的扫描逻辑:

推荐的文件整理流程:

mermaid

具体操作命令

# 创建统一导入目录
mkdir -p /data/photos/google-import

# 解压所有Takeout分卷到临时目录
unzip "Takeout-*.zip" -d /tmp/takeout

# 合并所有媒体文件到统一目录(保留日期结构)
find /tmp/takeout/Google\ Photos -type f \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.mp4" \) -exec sh -c '
    for file do
        # 提取日期信息(优先使用EXIF,无则使用文件名)
        date=$(exiftool -d "%Y-%m" -CreateDate -s3 "$file" || echo "unknown")
        dest="/data/photos/google-import/$date"
        mkdir -p "$dest"
        cp "$file" "$dest/"
    done
' sh {} +

# 删除重复文件(保留最新版本)
fdupes -rdN /data/photos/google-import

3.2 使用LibrePhotos扫描命令导入

LibrePhotos提供了强大的命令行工具处理批量导入,针对Google相册迁移,我们需要组合使用scansave_metadata命令:

基础扫描命令:
# 执行完整扫描(首次导入推荐)
python manage.py scan --full-scan

# 仅扫描新增文件(后续增量更新)
python manage.py scan

# 扫描指定文件(用于修复个别文件)
python manage.py scan --scan-files "/data/photos/google-import/2023-01/IMG_1234.jpg"
扫描过程解析:

mermaid

3.3 元数据保存与修复

Google相册的元信息部分存储在独立JSON文件中,需要通过额外步骤整合到照片文件中:

元数据保存命令:
# 批量保存元数据到文件(支持EXIF和XMP)
python manage.py save_metadata

# 检查元数据保存状态
grep -r "Rating" /data/photos/google-import/**/*.xmp
Google JSON元数据手动整合方案:

由于LibrePhotos目前不直接支持解析Google Takeout的JSON元数据,可使用以下Python脚本批量提取JSON信息并写入EXIF:

import json
import os
import exiftool

# 配置exiftool路径
exiftool_path = "/usr/bin/exiftool"
# 照片目录
photo_dir = "/data/photos/google-import"

with exiftool.ExifToolHelper(exiftool_path) as et:
    # 遍历所有JSON元数据文件
    for root, dirs, files in os.walk(photo_dir):
        for file in files:
            if file.endswith(".json") and not file.startswith("."):
                json_path = os.path.join(root, file)
                media_path = json_path[:-5]  # 移除.json扩展名
                
                # 检查对应的媒体文件是否存在
                if not os.path.exists(media_path):
                    continue
                    
                # 解析JSON元数据
                with open(json_path, 'r') as f:
                    metadata = json.load(f)
                    
                # 准备要写入的EXIF标签
                exif_tags = {}
                
                # 处理标题和描述
                if "title" in metadata:
                    exif_tags["Title"] = metadata["title"]
                if "description" in metadata and metadata["description"]:
                    exif_tags["ImageDescription"] = metadata["description"]
                    
                # 处理地理位置信息
                if "geoData" in metadata and metadata["geoData"]:
                    exif_tags["GPSLatitude"] = metadata["geoData"]["latitude"]
                    exif_tags["GPSLongitude"] = metadata["geoData"]["longitude"]
                    exif_tags["GPSLatitudeRef"] = "N" if metadata["geoData"]["latitude"] >=0 else "S"
                    exif_tags["GPSLongitudeRef"] = "E" if metadata["geoData"]["longitude"] >=0 else "W"
                    
                # 处理评分(Google相册星级 -> EXIF Rating)
                if "starred" in metadata and metadata["starred"]:
                    exif_tags["Rating"] = 5  # 将Google星标转换为5星评级
                
                # 写入EXIF数据
                if exif_tags:
                    et.set_tags(media_path, exif_tags, params=["-overwrite_original"])
                    print(f"Updated EXIF for: {media_path}")

脚本使用方法

# 保存为google_metadata_to_exif.py
# 安装依赖
pip install exiftool-python

# 执行转换
python google_metadata_to_exif.py

四、元信息保留深度解析

4.1 关键元数据字段迁移对照表

确保迁移过程中不丢失重要信息,以下是Google相册与LibrePhotos元数据字段的映射关系:

Google相册元数据存储位置LibrePhotos对应字段保留方法
拍摄日期时间EXIF/JSONexif_timestamp自动通过scan命令导入
地理位置EXIF/JSONexif_gps_lat/lon需手动转换JSON到EXIF
照片标题JSONPhoto.title通过自定义脚本写入EXIF Title
描述JSONPhoto.description通过自定义脚本写入ImageDescription
星级评分JSONPhoto.rating通过自定义脚本写入EXIF Rating
人物标签EXIF/JSONFace.person需要LibrePhotos人脸识别重新处理
相册分类目录结构AlbumUser通过LibrePhotos Web界面手动重建
修改日期文件系统Photo.last_modified自动保留

4.2 高级元数据处理:从XMP到数据库

LibrePhotos采用双轨制元数据管理策略,理解这一机制对数据完整性至关重要:

mermaid

元数据优先级规则

  1. 数据库中的元数据优先于文件系统元数据
  2. XMP侧栏文件元数据优先于EXIF数据
  3. 用户在Web界面编辑的元数据会覆盖所有来源
  4. save_metadata命令会将数据库元数据写回文件系统

五、迁移后验证与优化

5.1 数据完整性检查清单

迁移完成后,执行以下检查确保数据完整:

### 照片数量验证
- [ ] 源文件总数: `find /tmp/takeout -type f | wc -l`
- [ ] 导入后总数: `sqlite3 /data/librephotos/db.sqlite3 "SELECT COUNT(*) FROM api_photo;"`
- [ ] 差异分析: 确保差异在合理范围内(<5%)

### 元数据完整性检查
- [ ] 日期范围覆盖: 确认最早和最新照片日期正确
- [ ] 地理位置分布: 在地图视图检查位置标记是否存在
- [ ] 评分数据: 随机抽查带星标的照片是否保留评级
- [ ] 人像识别: 检查人物相册是否生成(可能需要24小时处理)

### 性能优化检查
- [ ] 缩略图生成: 确认所有照片都有缩略图
- [ ] 数据库索引: 检查api_photo表索引是否正常
- [ ] 存储空间: 验证实际占用空间是否合理

5.2 性能调优建议

对于大型照片库(10,000+照片),建议进行以下优化:

数据库优化:
# 分析并优化数据库表
sqlite3 /data/librephotos/db.sqlite3 "ANALYZE;"
sqlite3 /data/librephotos/db.sqlite3 "REINDEX;"

# 增加数据库缓存大小
echo "PRAGMA cache_size = -2000000;" >> /data/librephotos/db.sqlite3
媒体文件优化:
# 为照片生成合适尺寸的缩略图
python manage.py build_similarity_index

# 清理未使用的临时文件
python manage.py clear_cache

六、结语与进阶方向

恭喜!你已成功将Google相册数据迁移到LibrePhotos,实现了照片数据的完全自我托管。迁移后,建议定期执行以下维护任务:

# 每周维护计划
0 2 * * 0 python manage.py scan          # 每周日凌晨2点执行增量扫描
0 3 * * 0 python manage.py save_metadata # 保存元数据更改
0 4 * * 0 fdupes -rdN /data/photos/      # 移除重复文件

进阶探索方向:

  1. 自动化元数据处理:开发Google Takeout JSON专用导入插件
  2. 相册结构迁移:编写脚本将Google相册结构转换为LibrePhotos相册
  3. 机器学习增强:优化人脸识别模型提高人物标签迁移准确率
  4. 增量同步:实现Google相册到LibrePhotos的实时同步机制

LibrePhotos作为活跃开发的开源项目,正在不断改进数据导入功能。你可以通过GitHub Issues提交功能建议,或通过Discord社区分享你的迁移经验。


如果觉得本指南有帮助,请:

  • 点赞本文以帮助更多用户
  • 收藏以备将来参考
  • 关注项目发展获取更新通知

【免费下载链接】librephotos A self-hosted open source photo management service. This is the repository of the backend. 【免费下载链接】librephotos 项目地址: https://gitcode.com/GitHub_Trending/li/librephotos

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值