一张照片,除了画面,还藏着一小段"出生信息":什么时候拍的、用什么拍的、光圈快门多少。但是——只要经过一次社交软件的转存,这段信息多半已经被削掉大半。
这篇讲的是:被削过的照片,还能查出多少;以及为什么有的救得回、有的救不回。
先把三个词说白:
- EXIF:照片文件里自带的信息区(拍摄时间、设备型号、曝光参数,有的还有定位)。拍照时由相机写进去
- 转存 / 压缩:把照片发给别人或存到相册时,应用通常会把图重新压一遍、顺手删掉信息,为的是省流量、护隐私
- 二进制扫描:不走现成的读取库,直接按文件格式去翻字节,把库里读不到的标签也翻出来
先说清楚用了什么
| 环节 | 用的东西 | 这玩意是干嘛的 |
|---|---|---|
| 运行环境 | 手机上的终端工具 + Python 3.12 | 终端工具 ≈ 手机里的命令行窗口 |
| 解析 EXIF | Python 标准库 | 直接按图片文件的结构翻标签,不必装 Pillow 这类库 |
| 找文件 | find |
命令行里按名字 / 位置筛文件 |
| 算时间 | 一行 Python | 把文件名里的 13 位时间戳换算成可读时间 |
| 对照用 | 现成的读取库(如 Pillow) | 快速读基础信息可以,但被压过的图往往只读得到 6 条左右,所以要"往下挖" |
怎么用(三步)
① 先找到要查的照片
# 社交软件存下来的图多半在相册目录里,名字是「13 位时间戳」那种
find /sdcard/Pictures/ -name "mmexport*.jpg" -exec ls -la {} ";"
② 二进制扫描,把标签全翻一遍
python3 读exif.py 那张图.jpg
脚本做四件事:定位文件里的信息段 → 解析目录 → 逐个标签取值 → 打印结果。
重点看:拍摄时间、厂商、机型、曝光时间、光圈、ISO、焦距。
③ 顺手看文件名里的时间戳(它通常不是拍摄时间)
python3 -c "import datetime; print(datetime.datetime.fromtimestamp(1783485661949/1000))"
为什么普通库读不到,二进制扫描能多读到
照片里的信息是按目录嵌套存的:有一个主目录,主目录下面还挂着一个"扩展目录",很多关键参数(拍摄时间、曝光参数)恰恰藏在扩展目录里。
常规读取库只把主目录里最常见的几条取出来——在被压过的图上,那就是六条左右。二进制扫描是自己去翻字节,把扩展目录一并解析,所以能多挖出几条。所谓"技术含量"就这一点,没有别的黑科技。
能救回 / 救不回(如实说)
可能救回的
- 拍摄时间、机型、光圈快门 ISO 焦距——前提是这些信息还在文件里(很多应用会保留一部分)
- 保存 / 下载时间:从文件名里的 13 位时间戳换算,一定拿得到(但那是"存下来的时间",不是快门时间)
基本救不回
- 经过多次转发、朋友圈二次压缩、网页截图的图:信息往往被整段删掉,不是"藏得深",是真的没有了
- 原图本身就是截图:截图没有快门参数,只有截图那一刻
所以正确预期是:尽力挖,挖不到就是真丢了。
五个容易踩的点
- 时间戳糊涂账:文件名里的时间戳是"保存时间",和"拍摄时间"是两码事,写文档时别搞混
- 别指望一个方法通吃:被压过的图,常规工具读到的条数会明显偏少——这本身就是"该换方法"的信号
- 只读不写:解析脚本只读文件,别"顺手修复"——改写真值会破坏原图
- 隐私:EXIF 里的定位比照片本身更敏感,查出来的坐标自己知道就行
- 别一上来扫整个相册:先拿一张试,确认能读出信息,再批量
名词小抄(读不懂就翻这里)
| 词 | 一句话解释 |
|---|---|
| EXIF | 照片里自带的信息区:时间、设备、曝光参数,可能含定位 |
| 标签(Tag) | EXIF 里的一条信息,用编号区分(比如拍摄时间是一个编号) |
| 主目录 / 扩展目录 | 信息按层嵌套存放,关键参数常在扩展目录里 |
| 信息段 | 图片文件里专门装 EXIF 的那一段 |
| 二进制扫描 | 不依赖现成库,自己按文件结构翻字节 |
| Unix 时间戳 | 用"从 1970 年起的秒数"表示时间;文件名里的是毫秒版 |
| 元数据 | 数据的数据——对照片来说就是"关于这张照片的信息" |
🛠 本文由自建 Agent 调度内容流水线自动完成:写稿 → 模型 API 生图 → R2 图床 → 排版 → MCP 落站。
配图由模型 API 生成、托管在自建对象存储上;内容仅供参考。