用 iPhone 拍一张照片,再用十六进制编辑器打开这个 JPEG。从 FF D8 起始标记往后数几百字节,你会看到这段内容:
FF E1 1C 24 45 78 69 66 00 00 4D 4D 00 2A 00 00 00 08
FF E1 是 APP1 段标记。它后面的两个字节是段长度。接着六个字节拼出 Exif\0\0,紧随其后的是一个 TIFF 头(4D 4D 00 2A 表示大端序)。你的 JPEG 里还装着第二个更小的文件,它透露出的关于你的信息,往往比图像本身还多。
EXIF 到底是什么
EXIF 是 Exchangeable Image File Format(可交换图像文件格式)的缩写。JEIDA(日本电子工业振兴协会)于 1995 年发布了 1.0 版本。如今该标准由 JEITA 和 CIPA 维护,EXIF 3.0 于 2023 年发布。
从结构上看,EXIF 就是一个 TIFF。Exif\0\0 头之后是字节序标记,然后是一串图像文件目录(Image File Directory,IFD)。每个 IFD 条目固定十二字节:
Bytes 0-1: 标签 ID(如 0x010F = Make)
Bytes 2-3: 数据类型(ASCII、rational、short、long)
Bytes 4-7: 值的数量
Bytes 8-11: 内联值,或指向值的偏移量
有两个子目录和隐私直接相关。EXIF SubIFD(由标签 0x8769 指向)保存相机参数、序列号和时间戳。GPS IFD(标签 0x8825)把纬度和经度各存为三个有理数:度、分、秒。
IFD1 里通常还存着一张缩略图,一张嵌在元数据里的小 JPEG。先记住这一点,后面会用到。
哪些容器携带 EXIF:
| 格式 | EXIF 位置 | 说明 |
|---|---|---|
| JPEG | APP1 段 | EXIF 的发源地 |
| HEIC | meta box 中的 Exif 项 | 自 iOS 11 起的 iPhone 默认 |
| WebP | VP8X 内的 EXIF chunk | 可选,常常不存在 |
| PNG | eXIf chunk | 2017 年才加入规范 |
| TIFF | 文件本身就是 TIFF | EXIF 的母格式 |
| BMP/ICO | 不支持 | 完全没有元数据结构 |
相机为什么开始写入它
九十年代中期要解决的问题很琐碎,也很实际。数码相机产生的文件没有任何上下文信息。胶片摄影师有底片、印着冲印日期的相馆信封和笔记,数码相机用户有的只是一个装满 DSC_0042.JPG 的文件夹,别的什么都没有。
EXIF 解决了三个具体需求:
- 曝光记录。光圈、快门速度、ISO 和焦距,摄影师可以回看一张照片为什么拍得好,然后重复同样的设置。
- 打印下单。DPOF(Digital Print Order Format,数码打印命令格式)让你在相机上选好照片,之后由冲印店的自助机打印,其中会用到旋转等 EXIF 字段。
- 方向与预览。Orientation 标签让竖拍的照片保持竖直显示,内嵌缩略图让相机液晶屏上的浏览足够快。
注意这背后的前提:照片始终留在主人手里。在 EXIF 设计的世界里,一张照片的路径是从 CF 卡到硬盘再到冲印亭。1995 年的 JEIDA,没有人会想到有一天你每天会往公共服务器上传十几张照片。
里面到底装了什么
用任何一个元数据读取工具打开一张手机照片,标签列表都会很长。其中和隐私相关的字段:
| 标签 | 示例值 | 泄露了什么 |
|---|---|---|
| Make / Model | Apple, iPhone 15 Pro | 你的硬件 |
| BodySerialNumber / LensSerialNumber | 每台设备唯一 | 你相机的指纹 |
| DateTimeOriginal + OffsetTime | 2026:06:30 18:42:11 +09:00 | 时间,精确到秒 |
| GPSLatitude / GPSLongitude | 37°46'29" N, 122°25'10" W | 地点,精确到米 |
| GPSAltitude | 14.2 m | 大致哪一层楼 |
| Software | Instagram, Photoshop 26.1 | 哪些软件动过这个文件 |
| Artist / Copyright | 自由文本 | 有时是真名 |
| IFD1 缩略图 | 第二个 JPEG | 未经编辑的原图副本 |
下面是一张真实 iPhone 照片的 exiftool 输出,为简洁起见做了删减:
$ exiftool IMG_4021.HEIC
Make : Apple
Camera Model Name : iPhone 15 Pro
Serial Number : F2LX8A1BCD
Date/Time Original : 2026:06:30 18:42:11
GPS Latitude : 37 deg 46' 29.28" N
GPS Longitude : 122 deg 25' 10.41" W
GPS Altitude : 14.2 m Above Sea Level
花三十秒读完,一个陌生人就能知道你用什么设备拍、什么时候在那里,以及"那里"具体是哪里,误差不过几米。
在自己的电脑上查看 EXIF
Windows
右键点击文件,打开"属性",切换到"详细信息"选项卡。制造商、型号、日期和 GPS 坐标都列在里面。选项卡底部有一个"删除属性和个人信息"链接,点开是一个简单的元数据清除对话框。
想在 PowerShell 里直接读原始数据:
Add-Type -AssemblyName System.Drawing
$img = [System.Drawing.Image]::FromFile("C:\photos\IMG_4021.jpg")
$img.PropertyItems | ForEach-Object {
$text = [System.Text.Encoding]::ASCII.GetString($_.Value).Trim([char]0)
"Tag 0x{0:X4} (len {1}): {2}" -f $_.Id, $_.Len, $text
}
$img.Dispose()
数值字段读出来是原始字节,但 Make、Software 这类 ASCII 标签能正常显示出文字。
macOS
用"预览"打开图片,在"工具"菜单中选择"显示检查器",查看 EXIF 和 GPS 选项卡。GPS 选项卡甚至会把拍摄位置直接标在地图上。
在终端里,mdls 会列出 Spotlight 索引到的全部信息:
mdls IMG_4021.jpg | grep -iE "gps|latitude|longitude|model"
或者用 brew install exiftool 安装 ExifTool,查看完整的标签列表。
Linux
ExifTool 是标准工具:
exiftool IMG_4021.jpg
更轻量的替代方案:exiv2 IMG_4021.jpg,或者 ImageMagick 的 identify -verbose IMG_4021.jpg | grep -i exif。
在浏览器里,用二十行 TypeScript
想自己找到 APP1 段,需要沿着 JPEG 的标记链遍历一遍:
async function findExifSegment(file: File): Promise<number> {
const bytes = new Uint8Array(await file.slice(0, 128 * 1024).arrayBuffer())
if (bytes[0] !== 0xff || bytes[1] !== 0xd8) return -1 // not a JPEG
let offset = 2
while (offset < bytes.length - 12) {
if (bytes[offset] !== 0xff) break
const marker = bytes[offset + 1]
const length = (bytes[offset + 2] << 8) | bytes[offset + 3]
if (
marker === 0xe1 &&
String.fromCharCode(...bytes.slice(offset + 4, offset + 10)) ===
"Exif\0\0"
) {
return offset
}
offset += 2 + length
}
return -1
}
EXIF 如何泄露你的隐私
GPS 坐标暴露你的位置
只要相机应用有定位权限,手机拍照时就会记录 GPS,而这个权限是大多数人随手点过一次就忘掉的默认设置。把阳台、书桌或者孩子学校作业的照片发到论坛或二手交易平台,你就以米级精度公布了自己的住址。
最有名的例子是 John McAfee。2012 年 12 月,他在逃亡途中藏身危地马拉。Vice 发布了一张用 iPhone 4S 为他拍摄的照片,EXIF 数据里带着完整的 GPS 坐标,任何人都能读出他在危地马拉的确切位置。几天后,他被危地马拉警方拘押。
序列号把你的账号关联起来
BodySerialNumber 和 LensSerialNumber 每台设备唯一。两个匿名账号如果发布的是同一台相机拍的照片,就几乎可以被确定地关联起来。有研究者正是出于这个原因爬取图片网站,按相机序列号给照片聚类。你可以在网上把不同身份分开,你的相机却不分这些。
时间戳勾勒出你的作息
DateTimeOriginal,再加上时区偏移。单个时间戳说明不了什么,但一年的上传记录足以看出你几点起床、几点出门、什么时候旅行。
缩略图会出卖你
IFD1 缩略图是元数据里一张独立的 JPEG。把人脸或文件从主图中裁掉,很多编辑器并不会同步更新原始缩略图。谁把它提取出来,谁就拿到了未裁剪的原图。2003 年,一位 TechTV 主持人发布了裁剪过的个人照片,读者从 EXIF 缩略图中还原出了完整画面。这个教训流传至今,因为工具一直在犯同样的错误。
哪些上传渠道会留下 EXIF
大型社交平台(Facebook、Instagram、X)会在上传时剥离图片的 EXIF。其余渠道大多不会:邮件附件、论坛上传、交易平台商品图、网盘分享链接、AirDrop,以及任何设置为发送原图的即时通讯工具。只要文件原样离开你的设备,元数据就跟着一起走。
转换格式时会发生什么
转换照片格式并不自动等于清除元数据。转换器分两种:
- 元数据搬运工。重新编码但刻意把标签带过去的工具:ExifTool、ffmpeg,以及大多数默认勾选"保留元数据"的图形界面转换器。用这类工具把 JPEG 转成 WebP,你的 GPS 坐标会原封不动地搬进 WebP 的
EXIFchunk。 - 像素重编码器。先把文件解码成原始像素,再从像素编码出一个全新的文件。输出里只有图像数据,因为元数据从来就不是像素的一部分。
手动清除的话,两种方式都只需要一条命令:
# ExifTool: wipe every tag, keep the image
exiftool -all= -overwrite_original photo.jpg
# ImageMagick 7: re-encode without metadata
magick photo.jpg -strip photo-clean.jpg
这里有一个细节需要注意:方向。EXIF Orientation(标签 0x0112)告诉查看器把图像旋转一定角度,通常是 90 度。如果清除标签时没有把这个旋转烘焙进像素,每张竖拍照片导出来都是横躺的。正确的顺序是先按方向信息解码,再丢弃元数据。一个只清除不旋转的工具,比完全不清除还糟糕。
我们的转换器如何处理 EXIF
本站所有转换器都是像素重编码器,处理流程完全一致:
- 在你的浏览器中把源文件解码为原始像素(HEIC 使用 libheif 的 WebAssembly 版本,其余格式使用浏览器原生解码器)。
- 把像素绘制到画布上,EXIF 方向已在解码时应用完毕。
- 把画布编码为目标格式。
输出文件里只有压缩后的像素,别的什么都没有。没有 APP1 段,没有 EXIF 或 eXIf chunk,没有 GPS IFD,没有序列号,没有内嵌缩略图。代码里根本不存在复制元数据的路径,因为内存里就没有元数据可复制。而且整个流程都在客户端运行,文件从不离开你的设备,也没有任何服务器会看到原图。
选择你的源格式:
- iPhone 照片(携带的 EXIF 数据最多):HEIC 转 JPG、HEIC 转 PNG、HEIC 转 WebP
- JPEG:JPG 转 PNG、JPG 转 WebP、JPG 转 ICO
- WebP:WebP 转 JPG、WebP 转 PNG、WebP 转 ICO
- PNG:PNG 转 JPG、PNG 转 WebP、PNG 转 ICO
把文件拖进来,下载转换后的副本,分享这个副本。像素一模一样,元数据已经没了。
简而言之
- 在把照片分享到任何 EXIF 能保留下来的渠道(邮件、论坛、交易平台、直链)之前,先检查一遍。Windows 用"属性",macOS 用"检查器",Linux 用
exiftool。 - 如果文件带着 GPS 数据,而你并不希望如此,转换一下。上面链接的每个工具都只输出像素。
- 如果你用不同的身份发帖,相机序列号可能把这些身份关联起来。清除元数据同样能解决。
- 原图保持原样。在你自己的档案库里,EXIF 确实有用。需要干净的,是你发布出去的那些副本。



