| name | photo-distill |
| description | 把一张照片蒸馏成极简 zine 纸质海报——不用图像生成模型,用手写 HTML/CSS/SVG 绘制、 无头 Chrome 导出 PNG。当用户给出一张自己拍的照片、想把它做成极简海报/版画/zine 风格作品时使用。 触发词:照片蒸馏、photo distill、把这张照片做成海报、极简海报、zine 海报、 蒸馏这张照片、做成版画那种、用代码画这张照片、纸质海报、海报系列再做一张。 即使用户只说"把这张照片处理成那个风格"、"这张也来一张"、"帮我把这照片抽象一下", 只要是把摄影作品变成印刷符号,就应触发。 不用于 AI 生图海报(那用 gc-minimal-zine-poster)、照片修图调色、 或给现成图片套滤镜——本 skill 是从零绘制。
|
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
六、已用过的图形语言(别重复)
海平线+墨影人+吊圆 · 色层析柱 · 测距图 · 透视梯形窗 · 标本盘吊线 · 对角线草坡 ·
体块与缝 · 夜的墨块 · 仰视弧+细索扇+舱串 · 色块场+映射点阵 · 条纹织物+透光 ·
运动痕迹 · 路线牌+挡风玻璃里的落日 · 漂浮窗阵 · 天际线频谱 · 融化的穹顶 · 风景钻芯 ·
能见度阶梯/雾吃掉油墨 · 均质点场+三处异常 · 等高层线场+地形下切+垂直异物 ·
无边界墨气+云隙色斑+唯一硬边 · 密度梯度场/线自己出现 · 雨痕帘+红灯流淌 ·
测距墨点人+油画棒湖水 · 色票柱+三笔人+倒影 · 一方冷+亮从里让开/近糊远清 ·
内透的碎光点场 vs 投射的暖光团/纸兼作夜空与暗地 · 窗格线+一格绿+洒地的光
做新一张时先扫一遍这份清单,确认要用的语言没被用过;
选语言前先查 examples/structural-index.md
认结构类型——学那步棋,不抄那盘棋。用掉一个新语言就往清单里补一条。