AI 媒体元数据完整指南:EXIF、XMP、C2PA、PNG tEXt、MP4 全解析
几乎每个 AI 生成平台都会在导出的文件里留下点东西。有的写得大大方方,比如 Stable Diffusion 把完整提示词塞进 PNG 文本块;有的藏得很深,比如 Gemini 的 XMP 块可能出现在文件几 MB 之后的位置;还有的用了加密签名(C2PA)。这篇文章按文件格式逐一拆解这些元数据到底存在哪、长什么样、怎么读。文中提到的字段名、chunk 名和偏移量都来自 AICheck365 检测器的实际实现,不是泛泛而谈。
先建立一个直觉:元数据存在文件的哪里
一个图片或视频文件,本质上是"像素/帧数据 + 若干个元数据容器"。不同格式的容器机制不一样:JPEG 用段(segment),每段以 0xFF 加一个标记字节开头;PNG 用块(chunk),每块是 4 字节长度 + 4 字节类型名 + 数据 + 4 字节 CRC;MP4/MOV 用盒(box/atom),可以层层嵌套。EXIF、XMP、C2PA 这些标准各自占用其中一块或几块地方。
理解这一点之后,"为什么截图会丢失所有元数据"就不难解释了——截图工具只拿到了屏幕上的像素,重新编码成一个全新的文件,原文件里那些 segment、chunk、box 根本没机会跟过来。
1. EXIF:最老牌,也最容易被改
EXIF(Exchangeable Image File Format)1995 年就有了,最初是给数码相机记录拍摄参数用的,内部是 TIFF 风格的 IFD(Image File Directory)结构,在 JPEG 里放在 APP1 段。因为历史悠久、工具链成熟,它也是最容易被编辑和伪造的一类元数据。
和 AI 检测相关的字段主要有这几个:
Software:处理软件名。部分 AI 工具会老老实实写上自己的名字。Make/Model:相机厂商和型号。真实照片几乎都有,AI 生成图通常没有——个别工具反而会往这两个字段里写工具名。ImageDescription/UserComment:描述和注释字段,可能包含提示词或平台标识。Artist:创作者。有些平台在这里写入账号 ID 的哈希值——一长串十六进制字符(32 位以上),和正常人名的形态差别很大,本身就是一个弱信号。
UserComment 的一个坑
按 EXIF 规范,UserComment 的前 8 个字节是字符编码标识(比如 ASCII\0\0\0),真正的内容从第 9 个字节开始。很多简易查看器不处理这个前缀,直接把整个字段当十六进制显示,看起来像一堆乱码——实际上跳过前 8 字节再按 UTF-8 解码,内容就出来了。如果你自己写解析代码,这是必踩的坑之一。
国内平台的 AIGC 标识:藏在 UserComment 里的 JSON
这是近一两年才出现、但很值得了解的玩法。按照国内《人工智能生成合成内容标识办法》的隐式标识要求,部分国产平台会在 EXIF UserComment 里写入一段 JSON,形如:
{"AIGC":{"Label":"1","ContentProducer":"001191110000802100433B...","ProduceID":"..."}} Label 为 "1" 表示 AI 生成;ContentProducer 是内容生产者的注册编码,可以反查到具体平台——例如 001191110000802100433B 开头的编码对应通义(Qwen)生成图。这类标识因为是 JSON 文本,转发时只要 EXIF 没被剥离就还在,是判断国产 AI 图片来源时相当好用的线索。
反向启发式:相机字段集体缺失
真实照片的 EXIF 通常带一整套拍摄参数:FocalLength、FNumber、ExposureTime、ISO、Flash、MeteringMode、WhiteBalance……一张图如果 Software 字段命中了 AI 工具名,同时这十来个相机字段一个都没有,AI 来源的判断就更扎实一点。注意这只是辅助信号——经过修图软件导出的真实照片,也可能丢掉大部分拍摄参数。
2. XMP:Adobe 主导的 XML 元数据
XMP(Extensible Metadata Platform)是一段 RDF/XML 文档,以 <x:xmpmeta> 或 <rdf:RDF> 包裹,嵌在文件内部。在 JPEG 里它也放在 APP1 段(和 EXIF 共用段类型,靠开头的命名空间字符串区分);在 PNG 里放在关键字为 XML:com.adobe.xmp 的 iTXt 块中。
对 AI 检测来说,最重要的 XMP 属性是这些:
| 属性 | 典型值 | 说明 |
|---|---|---|
Iptc4xmpExt:DigitalSourceType | trainedAlgorithmicMedia | IPTC 定义的数字来源类型,AI 生成内容的标准声明方式 |
xmp:CreatorTool | 工具名,如 Midjourney | 创建工具,多数生成器会写 |
photoshop:Credit | Made with Google AI | 来源署名,Google 系生成图常见 |
AISystemUsed / AIPromptInformation | 系统名 / 提示词 | 较新的专用字段,目前写的平台不多 |
DigitalSourceType 的取值来自 IPTC 的受控词表,和 AI 相关的有六个:trainedAlgorithmicMedia(纯 AI 生成)、compositeWithTrainedAlgorithmicMedia(AI 参与合成/编辑)、compositeSynthetic(包含合成元素)、algorithmicMedia(算法生成,不一定经过训练)、dataDrivenMedia、trainedAlgorithmicData。前三个是强信号,后三个语义上弱一些。
一个实战细节:别假设 XMP 一定在文件开头附近。我们实测过 Gemini 导出的图片,XMP 块出现在文件相当靠后的位置,扫描窗口给小了就会漏掉——AICheck365 目前的扫描范围是文件前 10MB,就是被这类样本逼出来的。
3. C2PA:带数字签名的溯源记录
C2PA 和上面两类的本质区别在于:EXIF、XMP 是纯文本,谁都能改;C2PA manifest 经过 COSE 数字签名,改一个字节签名就失效。它在文件中以 JUMBF(ISO/IEC 19566-5)容器存放,具体位置取决于格式:JPEG 用 APP11 段(标记 0xFFEB),PNG 用专门的 caBX chunk,MP4 用 uuid box。
manifest 里对检测最有用的字段是 claim_generator / claim_generator_info(谁生成的,比如 Google 的图会写 "Google C2PA Core Generator Library")和 actions 断言里的 digitalSourceType(取值和上面 XMP 用的是同一套 IPTC 词表)。完整的结构拆解和验证方式,单独写了一篇:C2PA 标准解读。
4. PNG 文本块:Stable Diffusion 生态的"户口本"
PNG 原生支持三种文本块:tEXt(关键字 + \0 + Latin-1 文本)、iTXt(支持 UTF-8 和压缩,关键字后还有压缩标志、语言标签等字段,正文要跳过三个 \0 分隔符才开始)、zTXt(zlib 压缩文本)。本地部署的开源生成工具特别喜欢用它们存生成参数,而且存得非常全:
| 关键字 | 写入方 | 内容 |
|---|---|---|
parameters | AUTOMATIC1111 WebUI | 正负提示词、Steps、Sampler、CFG scale、Seed、模型哈希,一应俱全 |
prompt | ComfyUI | 提示词节点的 JSON |
workflow | ComfyUI | 完整节点图 JSON,可以直接拖回 ComfyUI 复现整个工作流 |
invokeai_metadata | InvokeAI | 生成参数 JSON |
Dream | 早期 SD 工具 | 提示词字符串 |
一段典型的 A1111 parameters 内容长这样:
masterpiece, best quality, 1girl, ...
Negative prompt: lowres, bad anatomy, ...
Steps: 28, Sampler: DPM++ 2M Karras, CFG scale: 7,
Seed: 3187702905, Size: 832x1216, Model hash: e3c47aedb0 命中这种块基本就是实锤——正常拍摄的照片里不可能出现采样器和 CFG 参数。但它的脆弱性也很明显:只要图片被另存为 JPEG,或者被任何不保留文本块的工具处理一遍,这些信息就全没了。所以我们在置信度上把 PNG 文本信号定得保守(低),更多是配合其他信号使用。
5. MP4 / MOV:视频容器里的三类线索
视频元数据比图片复杂一些,但思路一样。MP4 的元数据走 box 树:moov → udta → meta → ilst,其中 ilst 是条目列表,有两种寻址方式——经典的 iTunes 风格四字符键(©too 表示编码工具、©swr 表示软件),以及配合 keys box 的字符串键(QuickTime keyed metadata)。AI 视频检测主要看三类东西:
- 工具字段:
©too、©swr、encoder、tool、software这几个键的值如果命中已知 AI 工具名(Runway、Sora、Kling……),是中等强度的信号。有个有意思的实例:部分 Veo 导出的视频,©too的值就是干巴巴的一个 "Google"。 - AIGC 标签:和图片的 EXIF 版本对应,国产视频平台会在 ilst 里写一个键名为
AIGC的条目,值是 JSON:{"Label":"1","ProduceID":"...","ContentProducer":"..."}。ContentProducer同样可以反查平台,比如001191330106MA2CFLDG4R10001对应通义万相(Wan)。 - SEI marker:H.264/H.265 码流允许插入 SEI(补充增强信息)NAL 单元,部分平台在里面留了 ASCII 标记。在
mdatbox 的前 1MB 里做字节扫描,能找到kling-ai、sora、runway、pika-labs、luma-ai、hailuo、pixverse、vidu-ai这类字符串。SEI 藏在码流里而不是容器里,所以"重新封装但不重新编码"的操作(比如 MP4 转 MOV)反而删不掉它。
C2PA 也可以进 MP4(uuid box 里放 JUMBF),Sora 的部分导出就带。视频专题的完整流程见AI 视频检测指南。
各平台元数据写入习惯速查
下表是我们根据实际样本整理的大致情况,注意平台行为会随版本变化,仅供参考:
| 平台 | EXIF | XMP | C2PA | PNG 文本 | 视频侧 |
|---|---|---|---|---|---|
| Midjourney | 部分版本写 Description | 写 CreatorTool / DigitalSourceType | 无 | 部分 | —— |
| DALL-E 3 / GPT 图像 | 少量 | 有 | 有(OpenAI 签名) | 无 | 视频看 Sora |
| Gemini / Imagen | 少量 | Credit="Made with Google AI" | 有(Google 签名) | 无 | Veo 写 ©too |
| Stable Diffusion 系 | 少量 | 部分 | 无 | 主要载体 | 导出视频可抽帧 |
| Adobe Firefly | 有 | 有 | 有(创始成员) | 无 | —— |
| 通义 / 即梦等国产平台 | UserComment AIGC JSON | 部分 | 少见 | 少见 | ilst AIGC 标签 + 角标水印 |
| Sora / Kling / Runway / Pika | —— | —— | 部分 | —— | SEI marker / 容器字段 / 帧水印 |
怎么自己读这些元数据?
动手能力强的话,ExifTool 一个就够了,几条常用命令:
# 列出全部元数据,按来源分组
exiftool -a -G1 -s image.png
# 单独导出 UserComment 原始内容(看 AIGC JSON 用)
exiftool -b -UserComment image.jpg
# 提取 XMP 原文
exiftool -xmp -b image.jpg C2PA 用官方的 c2patool 或 Adobe 的 contentcredentials.org/verify 可以做完整的签名链验证。如果只是想快速看一个文件里有没有 AI 来源信号、不想装工具,AICheck365 在浏览器里就能把上面提到的所有位置扫一遍——文件在本地解析,不会上传。
把你手里的图片或视频拖进来,看看里面留了哪些来源信号
开始检测 →