如何从照片中提取 EXIF 数据
每张用数码相机或智能手机拍摄的照片都包含隐藏的元数据,称为 EXIF 数据。它记录了相机型号、快门速度、光圈、ISO、焦距、拍摄时间,以及——如果开启了位置服务——精确到几米的 GPS 坐标。
以下是读取它的方法。
EXIF 数据的样子
智能手机拍摄的典型 JPEG 包含如下字段:
| 字段 | 示例值 |
|---|---|
| Make | Apple |
| Model | iPhone 15 Pro |
| DateTime | 2025:09:14 14:32:05 |
| ExposureTime | 1/120 |
| FNumber | f/1.8 |
| ISO | 64 |
| FocalLength | 6.86 mm |
| GPSLatitude | 40° 42' 46" N |
| GPSLongitude | 74° 0' 21" W |
| Software | iOS 18.0 |
这个示例中的 GPS 坐标指向曼哈顿下城。如果你发布了一张在家拍的照片,除非先删除 EXIF,否则这些数据会随照片一起传出去。
在浏览器中读取 EXIF(无需软件)
基于浏览器的 EXIF 查看器在本地解析图片,无需上传。把照片拖进工具,它就会显示所有嵌入的元数据。不需要账号,不需要安装,没有数据被发送到任何地方。
这是一次性查询最快的选择——查看照片坐标、确认时间戳或验证相机设置。
用 Python Pillow 读取 EXIF
Pillow 库可以读取 JPEG 和 TIFF 文件的 EXIF 数据。
from PIL import Image
from PIL.ExifTags import TAGS
def read_exif(path: str) -> dict:
img = Image.open(path)
raw_exif = img._getexif()
if not raw_exif:
return {}
return {TAGS.get(tag, tag): value for tag, value in raw_exif.items()}
exif = read_exif("photo.jpg")
for key, value in exif.items():
print(f"{key}: {value}")
提取 GPS 坐标
GPS 数据以嵌套结构存储在 EXIF 中。以下是将其解码为十进制度的方法:
from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
def get_gps_coordinates(path: str):
img = Image.open(path)
raw_exif = img._getexif()
if not raw_exif:
return None
# 查找 GPSInfo 标签(标签号 34853)
gps_info = None
for tag, value in raw_exif.items():
if TAGS.get(tag) == "GPSInfo":
gps_info = {GPSTAGS.get(t, t): v for t, v in value.items()}
break
if not gps_info:
return None
def to_decimal(dms, ref):
degrees, minutes, seconds = dms
decimal = float(degrees) + float(minutes) / 60 + float(seconds) / 3600
if ref in ("S", "W"):
decimal = -decimal
return decimal
lat = to_decimal(gps_info["GPSLatitude"], gps_info["GPSLatitudeRef"])
lon = to_decimal(gps_info["GPSLongitude"], gps_info["GPSLongitudeRef"])
return lat, lon
coords = get_gps_coordinates("photo.jpg")
if coords:
lat, lon = coords
print(f"https://maps.google.com/?q={lat},{lon}")
ExifTool(命令行)
Phil Harvey 开发的 ExifTool 是最全面的 EXIF 读取工具,支持数百种格式——JPEG、TIFF、RAW 格式、视频、PDF 等。
# 安装
brew install exiftool # macOS
sudo apt install libimage-exiftool-perl # Ubuntu/Debian
# 读取文件的所有元数据
exiftool photo.jpg
# 读取特定字段
exiftool -DateTimeOriginal -GPSLatitude -GPSLongitude photo.jpg
# 提取文件夹中所有 JPEG 的 EXIF
exiftool -r /path/to/folder
# 输出为 JSON
exiftool -json photo.jpg
# 删除全部元数据(隐私保护)
exiftool -all= photo.jpg
删除 EXIF 数据保护隐私
如果你要公开分享照片,不想暴露 GPS 坐标或设备信息:
# ExifTool:删除所有元数据
exiftool -all= photo.jpg
# 删除并保留原始文件(保存 photo_original 备份)
exiftool -all= -overwrite_original photo.jpg
用 Python Pillow:
from PIL import Image
import io
def strip_exif(input_path: str, output_path: str):
img = Image.open(input_path)
# 仅从像素数据创建新图片——不含 EXIF
clean = Image.new(img.mode, img.size)
clean.putdata(list(img.getdata()))
clean.save(output_path)
哪些文件格式包含 EXIF?
| 格式 | EXIF 支持 |
|---|---|
| JPEG | 有——最常见 |
| TIFF | 有 |
| PNG | 无(使用不同的元数据:iTXt 块) |
| HEIC/HEIF | 有(现代 iPhone 格式) |
| WebP | 有限(基本 Exif 块) |
| RAW(CR2、NEF、ARW) | 有——完整的相机数据 |
| 无 EXIF(使用 XMP 元数据) | |
| 视频(MP4、MOV) | 无 EXIF,但在独立的原子中包含创建时间和 GPS |
要点总结
- EXIF 数据嵌入在 JPEG/TIFF 文件中,记录相机设置、时间戳和 GPS 坐标。
- 浏览器工具在本地处理文件——敏感照片无需上传。
- Python Pillow 处理基本 EXIF;ExifTool 用于跨所有格式的完整提取。
- EXIF 中的 GPS 坐标精确到足以定位家庭地址——分享前请先删除,如果隐私有顾虑的话。
- PNG 文件不使用 EXIF;改为查找 iTXt 或 tEXt 块。