Imported from yangcodingmaster/photo-distill (
SKILL.md). Install upstream withnpx skills add yangcodingmaster/photo-distill. Copyright stays with the author.
Photo Distill · 照片蒸馏成极简纸质海报
把照片蒸馏成三四个印刷符号——一块墨、一根线、一点色、一行小字,意思到了就停手。
产出是一个纯本地 HTML 文件(双击可开)+ 一张 2x PNG。全程零 AI 生图、零照片像素。
一、核心方法论
蒸馏,不是再现
走过的三条弯路,按顺序踩过一遍就懂了:
- ❌ 拼贴:从照片裁像素、做旧、贴上纸 → "只是抠图,不美观"
- ❌ 具象重绘:画完整场景(夜空背景 + 发光路灯 + 雾树线)→ 违反反向约束,"太具象"
- ✅ 抽象重绘:纸上印抽象符号。
例:路灯照片 = 米白纸 + 一小块竖长靛蓝墨块(夜)+ 一根细黑线穿过(灯柱)
- 线顶琥珀圆点带套印错位(灯)+ 墨块下方琥珀横条(被照亮的路)。
第三种是基准。海报可以完全零照片像素。
再往深一层:反向的语义过程
蒸馏的尽头不是"把物体画简单",而是先把照片剥到只剩关系,再只画那个关系。
正向语义是「看图 → 认出这是花和柏油」; 反向是「抽出关系(一片均质的场 + 三个异常点)→ 只画场与异常」。
判据:如果观者还在数花瓣,画的就仍是物体。
某张走了三版才到位:① 印一块黑、挖出花的形状 → 仍是物体; ② 撤掉沥青质感模拟 → 仍是物体; ③ 柏油与花统一成同一种符号(点),花 = 点阵让开的空处、场的边界自己稀疏掉 → 对了。
物体可以消失,但事实不能改——三处空处的坐标仍是从原片扫出来的那三个亮团中心。
二、工作节奏
开工自检:三个问题,实测回答,别"以为"
接到任务先测三件事。测不过就按对应的降级路径走,不许装:
- 能把 HTML 渲成 PNG 吗? 跑一次渲染命令试试(pipeline.md §4 有 macOS / Linux 两套路径)。不能 → 交 HTML 文件本体,让用户双击打开看
- 能看见渲染出来的 PNG 吗? 检验方式很具体:渲染后用一句话说出画面里的三个东西。 说不出来=你看不见=立刻进入下面的盲画协议。假装看见比看不见更糟—— 用户拿你说的三个东西一对照就拆穿了
- 能跑 Python + PIL 吗?
python3 -c "from PIL import Image"试一下。 不能 → 色值一个都不许编:把 design-system 的默认色板拿给用户选,或请用户直接报颜色
同一会话内已实测过的能力可复用结果,不必每张重测;换环境或换会话必须重测。
盲画协议(第 2 问答"否"时强制生效):第一版按采样数据画完立刻交给用户, 并明说"我看不到渲染结果,请你看图告诉我哪里不对";此后每一轮改动只能由用户反馈驱动—— 一条反馈 → 一处修改 → 立刻再交;自发迭代次数为零。你看不见,盲改一版都是浪费。
速度是第一指标:从拿到照片到用户看到第一张图,目标 5 分钟以内。 一张一张做,不批量。让用户等 15 分钟再看到一张不满意的图,是这个 skill 最大的失败模式。
解构,只取两三个元素。 不需要把照片里所有东西都表现出来—— 整张只选两三个元素,选哪几个用户说了算:
- 用户点名了("突出黄色的光晕和城市的内透")→ 这就是方案,直接开画
- 没点名 → 只问一句:"这张里你最想留下的两三个元素是什么?"
- 用户让你定 → 自己挑两三个,开画前用一两行说清"什么变成什么、色锚是什么",不等回复
选中元素之外的一切:不采样、不绘制、不惋惜。抽象程度由此自然落定—— 元素少即抽象;用户想更具象,自然会多点几个元素。
- 读事实(半分钟):比例、EXIF,一条命令出齐
- 最小采样(一个脚本,一分钟):只采选中元素的关系量——中心位置、密度、 一条分界 y、色相/饱和度,顺手算出色锚的目标面积(先算后画,别画完再测着调)。 绝不采轮廓——轮廓是物体的形状,采了就会忍不住去画 (实测:树梢的 141 个锯齿点,让一道横痕被画成了山)。 透视三步法(craft-rules.md §A)只在选中元素含地面线/结构时才走
- 直接带质感画:从 assets/template.html 起步一步到位。 不出低保真草图——实测草图阶段会自己长出迭代循环,省不了时间
- 截一张图 → 看图自检一轮 → 马上交给用户。首版之后你有且只有这一轮自查 (只修缩略图上看得见的错误);未经用户输入连改两版=违反协议。 每次交付必须带三样:图本体、一句话说明这版改了什么、一个明确的问题("哪里要调?")。 用户一句"黑的像山"顶你五轮自查;千分之几亮度差的像素级缺陷不追
- 用户反馈 → 小改快出:每轮改动一步到位,30 秒内重新出图,不憋大招
- 用户说行才定稿:跑
scripts/finalize_poster.py(渲染 2x + 四项实测一条命令, FAIL 即删,PASS 才有成品;用户确认过的偏离用--waive显式记录)→ git commit。 非本机环境交付时附 6 行运行日志(run-log-template.md)
三、硬性规则
- 画幅 = 原片比例(横竖都跟原片)。高度用脚本算,别估
- 不带任何文案短句。只带真实拍摄参数——这是与文艺海报的分界线
- 每张一个独立的图形语言,不与此前作品重复。做之前先翻一遍已有的清单
- 进成品的每个数字必须脚本算(坐标映射、几何端点、透视落点、色锚面积)
- 色锚四条硬指标:占画布 0.8–2.5%、缩略图下可见、绝不用 pale/muted 削弱、单一主色相
- 不做材质模拟。沥青碎石、木纹、水波都是再现。唯一允许的质感是标准颗粒层
- 纸读作 70–90%,主体着墨 8–25%(按实际着墨算,不按外框)
- 定稿前逐条对反向约束清单
定稿实测(脚本跑成品 PNG,四个数一次出,别靠眼估)
唯一真身是 scripts/finalize_poster.py——渲染 + 实测 + FAIL 即删(fail-closed),下表只是速览,阈值以脚本为准,别照表另写一份实现。
这四个数不是创作目标,是出厂检验。 用户说行之前,禁止为了凑指标修改画面; 创作阶段调色看图、看采样值,不看百分比。把检验标准当目标函数,画面不会变好, 只会产出几版"数字不同、肉眼没差别"的空转。
| 指标 | 怎么算 | 目标 |
|---|---|---|
| 色锚面积 | sat>0.35 且 v>0.12 的像素占比 |
0.8–2.5% |
| 缩略图可见性 | 缩到 160px 宽后重算上一项 | 仍 ≳0.6% |
| 实际着墨 | 与纸色的 RGB 曼哈顿距离 >46 的像素占比 | 8–25%(纸 70–90%) |
| 色相集中度 | 色锚像素色相的中位数与 5–95 分位 | 分位跨度窄=单一主色相 |
⚠️ 色相分桶会骗人:210° 附近的蓝按 30° 分桶会被切成两半,看着像"两个色相"。 用中位数 + 分位,别用直方图桶。
四、可自定义的六个槽位
最大的那个自定义维度是"抽象程度",它不在下表里——它由用户点名哪两三个元素 直接决定(见 §二)。下面六个是视觉常量,默认值是这套语言的原点, 用户要换时照表办,细节见 design-system.md §6。
| 槽位 | 默认 | 换的时候守什么 |
|---|---|---|
| 画幅 | 与原片同比例 | 一旦不跟原片,裁切本身就是蒸馏动作,要说明理由 |
| 字体 | Courier / Songti 栈 | 全站一个字体栈、禁用斜体——这两条不放开 |
| 纸色 | 米白 #e9e3d5 |
氛围优先进符号,不进纸。整张染成场景色 = 回到再现 |
| 色锚色板 | 按照片轮换 | 四条硬指标一条都不放宽 |
| 档案微字 | 三行真实参数 | 参数必须真实,宁可写 GPS — 也不编 |
| 编号系统 | NO. XXX + + 套准符 |
可换前缀、改位置、或关掉 |
不可自定义:噪点层参数、multiply 上纸、不做材质模拟、色锚四条硬指标、反向约束清单。
五、References
| 文件 | 内容 | 什么时候读 |
|---|---|---|
| design-system.md | 纸/墨/色锚/档案微字的全部常量与代码、反向约束清单、六个自定义槽位 | 搭骨架时、定稿对表时 |
| filters.md | 可直接复制的 SVG 滤镜库(揉边/颗粒/无边界墨气/渗边/油画棒)、mask 四用法、符号词汇 | 决定"这个符号怎么画"时 |
| craft-rules.md | 透视三步法、材质语法、雾/凹陷/色块/硬边的做法与失败案例、定稿自查清单 | 动手前和定稿前各一次 |
| pipeline.md | EXIF 提取、HEIC 方向坑、采样脚本约定、渲染与 2x 导出命令(macOS/Linux 双路径) | 开工第一步、导出时 |
| examples/structural-index.md | 结构类型 → 蒸馏手法的一行式索引(学那步棋,不抄那盘棋) | 给新照片选图形语言时先读这个 |
| examples/ | 八对「原片 → 成品」对照,每对说明蒸馏成了哪几个符号 | 索引命中后想看完整推演时 |
| scripts/finalize_poster.py | fail-closed 定稿:渲染 2x + 四项实测一条命令 | 只在用户说行之后 |
六、已用过的图形语言(别重复)
海平线+墨影人+吊圆 · 色层析柱 · 测距图 · 透视梯形窗 · 标本盘吊线 · 对角线草坡 · 体块与缝 · 夜的墨块 · 仰视弧+细索扇+舱串 · 色块场+映射点阵 · 条纹织物+透光 · 运动痕迹 · 路线牌+挡风玻璃里的落日 · 漂浮窗阵 · 天际线频谱 · 融化的穹顶 · 风景钻芯 · 能见度阶梯/雾吃掉油墨 · 均质点场+三处异常 · 等高层线场+地形下切+垂直异物 · 无边界墨气+云隙色斑+唯一硬边 · 密度梯度场/线自己出现 · 雨痕帘+红灯流淌 · 测距墨点人+油画棒湖水 · 色票柱+三笔人+倒影 · 一方冷+亮从里让开/近糊远清 · 内透的碎光点场 vs 投射的暖光团/纸兼作夜空与暗地 · 窗格线+一格绿+洒地的光
做新一张时先扫一遍这份清单,确认要用的语言没被用过; 选语言前先查 examples/structural-index.md 认结构类型——学那步棋,不抄那盘棋。用掉一个新语言就往清单里补一条。