起因是亚马逊 7 月 22 日给第三方卖家发的通知:商品图、A+ 内容和商品视频里,如果出现完全由 AI 生成的写实人物,上传前必须用支持 IPTC/XMP 的编辑器,把关键词 contains-synthetic-performer 写进图片 XMP 的 dc:subject 字段。背后是纽约州 General Business Law 396-b ( 6 月 9 日生效),首次违规民事罚款 1000 刀,之后每次 5000 刀。
写这个标签本身不难,exiftool 一行就完事了。真正麻烦的是另一件事:亚马逊是在你上传那一刻去读这个字段的,所以中间任何一个环节把它吃掉,结果和你从来没打过标一模一样。而我能找到的所有说法——平台公告、咨询机构的合规指南——都停在同一句话上:「某些系统会在导出时移除嵌入的元数据」。从来没有一份说过是哪些。
那就自己测一遍。每一步都从一张全新的 1200×1200 图开始,先打上标签,过一个处理步骤,再读回两次:一次用自己的读取器,一次用 Pillow 独立的 XMP 解析器,两个读数不一致的行就作废重来(这次没出现不一致)。另有一行「原样复制」当对照组——它要是也报丢,说明测量方法本身有问题,其余所有行全部作废。
结果:能脚本化测的 8 个处理步骤里,没有一个能在 JPEG 和 PNG 上同时保住标签。其中 5 个两种格式都丢,3 个 JPEG 活下来、PNG 死了。
处理步骤 |
JPEG |
PNG |
|---|
原样复制文件(对照组) |
保留 |
保留 |
Pillow 重新保存 |
剥掉 |
剥掉 |
Pillow 缩放后保存 |
剥掉 |
剥掉 |
Pillow 降质压缩 |
剥掉 |
剥掉 |
Pillow 保存时把 xmp= 传回去 |
保留 |
剥掉 |
macOS sips 缩放 |
保留 |
剥掉 |
macOS sips 转格式 |
保留 |
剥掉 |
ffmpeg 重编码 |
剥掉 |
剥掉 |
Squoosh ( mozJPEG / OxiPNG 默认档) |
剥掉 |
剥掉 |
三条我自己没想到的结论:
- 只要重新保存一次就可能丢。不用裁剪、不用调压缩、不用点导出对话框,单纯用 Pillow 打开再存一次,XMP 就没了。任何把图过一遍脚本的环节都值得怀疑。
- PNG 比 JPEG 脆。所有在 JPEG 上活下来的步骤,换成 PNG 全军覆没。
- 这是可以避免的,不是宿命。同一个 Pillow ,保存时多传一个
xmp= 参数,JPEG 就保住了。工具丢元数据是因为没人要求它保留,不是因为做不到。
另外两个是手工测的往返路径,单独说,因为它们比脚本那几行更有意思:
Canva 什么都没删。导出的文件里 XMP 还在——只不过换成了 Canva 自己那一份,描述的是 Canva 的文档,原本躺在 dc:subject 里的东西不在里面了。如果你的检查逻辑只是粗略问一句「这文件有没有元数据」,它能干干净净地通过,而真正要读的那个东西已经没了。这也是为什么验标必须报三种状态而不是两种:标签在 / 有元数据但没有标签 / 什么都没有。中间那种才是坑。
微信是这次最干净的一组对照,因为同一个 App 、同一个动作,只差一个勾选框,结果完全相反:
- 手机发送时勾上「原图」:SHA-256 与原文件一致,仍是 2752×1536 ,标签完好。
- 不勾(也就是默认):图被缩到 2293×1280 、体积只剩原来的 41%,XMP 整块消失。
- 桌面版「文件传输助手」:界面上根本没有原图选项,但收到的文件逐字节一致。
微信本身没什么特殊。它转交文件时标签活着,它重新编码时标签就死了——和表里每一行落在同一条线上。所以判断任何一个环节,该问的不是「这是哪个 App 」,而是它有没有重新编码这张图。压缩、缩放、转格式、编辑器打开再保存,都是;复制、打包、以文件形式发送,都不是。
顺手把工具也做了:https://disclosetag.com (中文版 https://disclosetag.com/zh )
- 拖进去先检测已有标签,只给缺的补,批量处理,出 ZIP 和一份逐文件的处理报告
- 读和写全在浏览器里跑,文件不上传,没有登录、没有付费墙、没有额度
- 图片写 XMP
dc:subject;视频那部分是实验性的——亚马逊到现在也没公布视频该用哪个元数据字段,我写的是容器标签( comment / description / keywords ),这个我不敢说它构成合规,页面上也是这么标的