You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python提取照片Exif数据异常:Mac显示有元数据但部分照片Exif字典为空的原因排查

问题分析与解决方案

我之前也碰到过一模一样的情况,结合你的场景和代码,咱们来拆解下背后的原因:

核心矛盾:元数据存储位置 + PIL的读取局限

  • Google Photos的导出特殊处理:那5%的照片从Google Photos下载后,拍摄日期等元数据并没有存在传统的Exif数据块里,而是被转移到了XMP元数据或者Mac系统维护的Spotlight索引中。Google Photos有时候为了压缩效率或格式兼容性,会把元数据放到这些非标准Exif的位置。
  • Mac显示元数据的“多源”特性:Mac的「显示简介」里的拍摄日期,并不只依赖Exif。它会优先读Exif,没有的话就去读XMP、IPTC,甚至直接用文件的创建/修改时间(Google Photos导出时经常会把拍摄日期同步成文件时间),或者调用Spotlight的数据库数据——所以你能看到,但脚本读不到。
  • PIL的getexif()能力边界:你用的Pillow(PIL)的getexif()方法,只专注于读取JPEG/PNG等格式里的传统Exif区块,对XMP、HEIC格式的元数据支持很差。如果元数据存在其他位置,它自然返回空字典。

验证与解决办法

1. 先确认照片格式

先检查那部分异常照片是不是HEIC格式?Mac原生支持HEIC,但Pillow默认不支持读取HEIC的Exif。如果是HEIC,先安装适配库:

pip install pillow-heif

再修改代码:

from pillow_heif import register_heif_opener
from PIL import Image
from PIL.ExifTags import TAGS

# 注册HEIC格式支持
register_heif_opener()

my_img = Image.open("one.heic")
exif_data = my_img.getexif()
for tagId in exif_data:
    tag = TAGS.get(tagId, tagId)
    data = exif_data.get(tagId)
    print(f"{tag:16}: {data}")

2. 读取XMP元数据

如果是JPG但元数据存在XMP里,换用exifread库,它能读取更多元数据格式:

pip install exifread

代码示例:

import exifread

with open("one.jpg", 'rb') as f:
    tags = exifread.process_file(f, details=True)
# 过滤掉无关的缩略图等标签
for tag in tags.keys():
    if tag not in ['JPEGThumbnail', 'TIFFThumbnail', 'Filename', 'EXIF MakerNote']:
        print(f"{tag:25}: {tags[tag]}")

这个库会扫描包括XMP在内的多种元数据区域,大概率能找到你要的拍摄日期。

3. 退而求其次:读取文件属性

如果以上方法都不行,那Mac显示的日期大概率是文件的创建/修改时间,用Python直接读取:

import os
from datetime import datetime

file_stats = os.stat("one.jpg")
print("文件创建时间(对应拍摄日期):", datetime.fromtimestamp(file_stats.st_birthtime))
print("文件修改时间:", datetime.fromtimestamp(file_stats.st_mtime))

Google Photos导出时经常会把拍摄日期同步为文件的创建时间,这也能作为备选方案。


内容的提问来源于stack exchange,提问作者RickRugby

火山引擎 最新活动