
免费
版画封面
把文章的论点变成一个视觉寓象,用脚本刻出一张黑白版画封面,画面里没有一个字
安装
把“版画封面”技能安装到 ~/.claude/skills/woodcut-cover。 下载下面每个文件,保存到这个文件夹: https://skilllift.pages.dev/packs/woodcut-cover/SKILL.zh.md → SKILL.md https://skilllift.pages.dev/packs/woodcut-cover/references/style.md → references/style.md https://skilllift.pages.dev/packs/woodcut-cover/references/elements.md → references/elements.md https://skilllift.pages.dev/packs/woodcut-cover/references/element-sheet.png → references/element-sheet.png https://skilllift.pages.dev/packs/woodcut-cover/assets/engine.mjs → assets/engine.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/graver.mjs → assets/graver.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/elements.mjs → assets/elements.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/scenes.mjs → assets/scenes.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/compose.mjs → assets/compose.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/spec.template.json → assets/spec.template.json https://skilllift.pages.dev/packs/woodcut-cover/scripts/render.mjs → scripts/render.mjs https://skilllift.pages.dev/packs/woodcut-cover/scripts/check.mjs → scripts/check.mjs https://skilllift.pages.dev/packs/woodcut-cover/scripts/svg-raster.mjs → scripts/svg-raster.mjs https://skilllift.pages.dev/packs/woodcut-cover/scripts/export-svg.mjs → scripts/export-svg.mjs https://skilllift.pages.dev/packs/woodcut-cover/scripts/sheet.mjs → scripts/sheet.mjs https://skilllift.pages.dev/packs/woodcut-cover/assets/examples/custom-element.spec.json → assets/examples/custom-element.spec.json https://skilllift.pages.dev/packs/woodcut-cover/assets/examples/headline-only.spec.json → assets/examples/headline-only.spec.json 然后读一遍 SKILL.md,告诉我它是做什么的,并提醒我开一个新会话。
解压到 ~/.claude/skills
同一个技能,不同的需求
左边是预览。右边由另一个 Agent 按不同需求制作,它只有安装好的技能,没看过预览。
这是按虚构需求做的一次测试。系统字体不同时,字形可能略有差异。
把一篇文章变成一张 16:9 黑白封面,画面里没有文字,全部由脚本生成,不用图像模型。先为文章的核心论点提出三个视觉寓象,选定一个,再用 96 个代码绘制的元素和一种真实的变形,以粗犷的版画线条构成画面。输出 2400x1350 PNG、1200x675 副本、可编辑 SVG 和一段短说明。当有人想给文章、随笔或通讯配一张有观点的封面,想要木刻或版画效果,或点名要这个风格时使用。
交付前必须通过
- 论点是一句有人会反对的话,或已标明出于推断。
- 考虑过三个寓象,放弃的两个有理由,选定的一个用一句话说清。
- 通过互换检验:这张图不适用于相反的论点。
- 一个物件,一种变形,最多三个辅助符号,摆放元素不超过 4 个。
- 冷读是看图后、看说明前写的,并且对上了论点。
- 每个元素都名副其实,没有近似替代。
- 在本技能文件夹运行
node scripts/check.mjs,退出码为 0。 - 亲眼看过 1200 宽和 600 宽,一眼能读出一个想法。
- 画面没有文字,说明只用一种语言。
- 虚构内容已标注,没有编造任何内容。
阅读完整 SKILL.md
---
name: woodcut-cover
description: 把一篇文章变成一张 16:9 黑白封面,画面里没有文字,全部由脚本生成,不用图像模型。先为文章的核心论点提出三个视觉寓象,选定一个,再用 96 个代码绘制的元素和一种真实的变形,以粗犷的版画线条构成画面。输出 2400x1350 PNG、1200x675 副本、可编辑 SVG 和一段短说明。当有人想给文章、随笔或通讯配一张有观点的封面,想要木刻或版画效果,或点名要这个风格时使用。
version: 1.0.0
---
# 版画封面
画面风格都在 `assets/` 里。你的工作是思考:找到论点,找到能说出这个论点的画面,然后写一份 spec。你不用画,也不用选风格。同样的 spec 和 seed,出来的画面完全相同。
这个技能包只有一种原创风格。如果有人要模仿某位具名艺术家、某个工作室或某幅现有版画,这部分要拒绝,用一句话说明,然后提供本风格。`render.mjs` 会拒绝 spec 任何层级的未知字段,也会拒绝寓象、说明或假设中“模仿某某风格”这类措辞。但它认不出自由文本里单独出现的人名,这一点靠你自己:绝不要写。
## 需要问的信息
只问缺的,一条消息问完。
1. 文章,或你能读到的链接。只有标题也可以,见“信息不足时”。
2. 想自己从三个寓象中选,还是由你选。默认由你选并说明理由。
3. 输出文件夹。默认 `./cover`。
不要问风格、颜色、字体或版式,这些都是固定的。
## 步骤
1. **找到论点。** 把论点写成一句有人会反对的话。话题不是论点:“注意力”是话题,“注意力是选择的结果,不是被偷走的”才是论点。
2. **提出三个寓象。** 每个寓象包含一个具体物件、一种奇异的变形,以及最多三个辅助符号。三个必须是不同的想法,而不是同一想法的三种画法。边想边查 `references/elements.md`。
3. **逐个检验。**
- 互换检验:它是否同样适用于相反的论点?是的话就放弃。
- 一瞥检验:能否用一句短话说出物件和它哪里不对劲?
- 陈词检验:灯泡代表想法、大树代表成长,这类画面什么也没说,放弃。
4. **选定一个并说明理由**,或者把三个都给用户选。用一句话说出这个寓象。
5. **核对每个名词。** 画里的每样东西都必须以这个名词出现在 `references/elements.md` 中。没有的话,见“制作缺少的元素”。
6. **写 spec。** 从 `assets/spec.template.json` 开始,填好下表的每个字段。
7. **先小图迭代。** `node scripts/render.mjs spec.json --out cover --small` 会生成 `cover/preview-600.png`。每次只渲染一张。
8. **冷读,必做。** 在重新看说明和寓象之前,先看 `preview-600.png`。把陌生人会说的话,用他们的语言写进 `cold_read`:`sees` 是画面画了什么,`argues` 是它似乎在主张什么。然后拿 `argues` 和论点对比。对不上就把 `verdict` 设为 `misses`:这张封面作废。先改构图,再换寓象,然后重新冷读。如果能把图单独交给不了解背景的人或工具看,就这样做。需要靠说明才看得懂的封面就是失败的。没有 `cold_read` 时,完整渲染会被拒绝。
9. **渲染。** `node scripts/render.mjs spec.json --out cover`。
10. **检查。** 用本技能里的脚本运行 `node scripts/check.mjs cover`。按提示修改,直到退出码为 0。
11. **亲眼看。** 看原尺寸和 `cover/preview-600.png`。检查通过不代表看得懂,脚本判断不了这一点。
## 交付物
输出文件夹里有:`cover.png`(2400x1350)、`cover-1200.png`(1200x675)、`cover.svg`(可编辑,每个元素一组)、`note.md`(论点、寓象、理由、画面与论点的关系、冷读、放弃的寓象)和 `spec.json`。`preview-600.png` 是缩小时带灰度的审看副本,不要交付。把图、一句话寓象和说明交给用户。
## Spec 字段
限制按字数计,`lang` 为 `zh` 时按汉字数,`en` 时按英文单词数。
| 字段 | 含义 | 限制 | 信息不足时 |
|---|---|---|---|
| `seed` | 整数。只改变刀痕和场景细节,不改变想法 | 整数 | 任意数字,记下来以便重做 |
| `lang` | 所有文字的语言 | `en` 或 `zh` | 跟随文章语言 |
| `sample` | true 表示在说明里标为示例文章 | true 或 false | 除非是示例,否则为 false |
| `article.title` | 标题,不会画进图里 | 40 字(英文 20 词) | 用给定的标题。文章没有标题时,原样用第一句,超长就用第一个分句,并写进 `assumptions`。绝不自拟 |
| `article.thesis` | 一句话论点 | 80 字(英文 40 词) | 以“暂定论点,仅从标题推断:”开头,写明你选择的理解 |
| `article.thesis_source` | 论点来源:`article`、`user`、`headline` 或 `inferred` | 一个词 | 只有标题用 `headline`,文章没有单一论点用 `inferred` |
| `allegory.sentence` | 一句话说出物件和奇异之处,必须包含每个主要元素的名词。主要元素指变形中点名的元素(`object`、`material`、`giant`、`a`、`b`、`shadow`、`from`、`to`),辅助符号和 `tiny` 不必写 | 70 字(英文 35 词),只能一句 | 规则不变,不因信息少而变含糊 |
| `allegory.object` | 那一个具体物件 | 一个名词 | 同上 |
| `allegory.why` | 为什么选它而不是另外两个 | 90 字(英文 45 词) | 说明“按这种理解”,再给理由 |
| `rejected` | 恰好两个没选的寓象,每个是 `{sentence, why}` | 70 字和 60 字(英文 35 和 30 词) | 仍要两个,理由可以是它们适合哪种理解 |
| `assumptions` | 你推断的所有内容 | 列表 | `headline` 和 `inferred` 时必填,列出缺什么、取了哪种理解 |
| `scene` | 场景,见 `references/style.md`:`setting`,可选 `key`、`horizon`、`shore`、`ground`、`beam` | 见下 | 选能让物件跳出来的场景,而不是话题联想到的场景 |
| `transformation` | 变形操作,见下 | 一种 | 按论点选,不要有默认选择 |
| `signs` | 辅助符号:`{element, x, y, h}`,可选 `rest`(`ground`、`sea` 或 `air`)、`flip`、`rot`(角度)、`params` | 0 到 3 个,全部摆放元素不超过 4 个 | 尽量不用 |
| `nouns` | 把用到的每个元素 id 对应到寓象里的叫法,如 `{"lighthouse":"灯塔"}`。英文名词的复数也接受,如 `{"chair":"chairs"}` | 用到的每个元素 | 同上,不允许近似替代 |
| `custom_elements` | 用基本图元搭建的元素 | 见下 | 只在想法确实需要时用 |
| `cold_read.sees` | 陌生人会说画面画了什么,用他们的话,看图后、看说明前写。不能照抄寓象句 | 80 字(英文 40 词) | 同样要写,信息少不是借口 |
| `cold_read.argues` | 陌生人会说它在主张什么 | 60 字(英文 30 词) | 同样要写,并与推断的论点对比 |
| `cold_read.verdict` | `argues` 对上论点填 `hits`,否则填 `misses`。`misses` 会被拒绝 | 一个词 | 同上 |
| `note` | 画面如何表达论点:什么代表什么。不是描述画面 | 180 字(英文 90 词) | 开头说明论点出于推断,是首先要确认的事 |
**摆放元素最多 4 个。** 计数包括变形点名的元素、每个 `tiny`、场景里的每个元素和每个辅助符号。一片拼贴或一条链,不管画了多少份,都只算它点名的两个元素。`render.mjs` 和 `check.mjs` 都会强制执行。想要一组东西,就用本身是一组的元素,如 `meeting-table`。
`x`、`y`、`h` 分别是占页面宽、高、高的比例,`y` 是元素底部所在位置。TODO、TBD、`<<槽位>>` 这类占位内容都不能通过检查。上面信息不足时推荐的开头不算占位内容,可以通过。
`beam` 写作 `{"to":[x,y],"spread":0.17}`,是横穿夜空的一道白色光束。`impossible_join` 中光束从第二个物件发出,其他情况要加 `"from":[x,y]`。把 `to` 定在画面之外,免得光束在画面内戛然而止。
## 场景与小物件
每个摆放的物件都有一圈白色光晕刻痕,细腿不会融进深色地面。即便如此:
- 小物件(低于页面高度 0.3)放在 `ground: dark` 上,底部靠近地平线,那里地面白色刻痕最多。细的东西压在下方纯黑上最难看清。
- `ground: light` 和 `room` 的地板黑线很密。适合大物件和影子,不适合小家具。
- 浅色物件配深色天空,深色物件配亮色天空。
## 六种变形
每张封面只用一种。每一种都是真实的几何操作,`example/` 里都有演示。
| `type` | 做什么 | 字段(默认值) | 例子 |
|---|---|---|---|
| `made_of` | 一物由另一物构成。B 的副本被裁进 A 的轮廓内,并按 A 的形体打阴影 | `object`、`material`、`x` .5、`y` .86、`h` .72、`tile` .115(不小于 .09) | 由挂锁组成的钟。物件轮廓要实,不能是拱门或框架,材料要接近方形 |
| `size_inversion` | 小东西变巨大,巨大的东西变渺小。现实中小物必须至少比对方小 3 倍,画面上大小也要相差至少 3 倍,否则拒绝渲染 | `giant`、`tiny` `[{element,x,y,h,rest,flip,behind}]`、`x` .5、`y` .86、`h` .8 | 蜡烛比灯塔还高。`rot` 让巨物倾斜。`tiny[].rest` 取 `ground`、`sea` 或 `air` |
| `impossible_join` | A 在接缝处被截断,B 从断口长出,两者共用一圈过渡 | `a`、`b`、`x` .5、`y` .88、`a_h` .8、`b_h` .45、`overlap` .03、`collar` .075 | 灯室换成眼睛的灯塔 |
| `scene_inside` | 物件里裁进一个完整场景,有自己的天空和地面 | `object`、`x`、`y`、`h`、`inside` `{setting, key, horizon, elements:[{element,x,y,h}]}`,其中比例相对于开口 | 手提箱里的风景 |
| `false_shadow` | A 站在光里,投下的影子却是 B。投在墙上时影子直立,最易读 | `object`、`shadow`、`surface` 取 `wall` 或 `ground`、`x` .32、`y` .84、`h` .3、`shadow_x` .56、`shadow_h` .72 | 硬币投下船锚的影子 |
| `chain_opposite` | A 的轮廓沿一条路径一步步变成 B 的轮廓 | `from`、`to`、`steps` 8、`path` `[[x,y],...]`、`from_h`、`to_h`、`hold_from` 2、`hold_to` 2、`connector` | 铁链变成飞鸟 |
带 `seam` 锚点的元素接合最干净,带 `window` 的元素最适合装场景。没有 window 时,整个轮廓都用来装场景。`impossible_join` 最好让 B 长在 A 原本就有意义的部位。
## 制作缺少的元素
如果寓象需要的东西不在元素库里,不要用相近的东西代替。手推车不是自行车,提灯也不是灯泡。`render.mjs` 会拒绝这种近似。要么换一个寓象,要么在 `custom_elements` 里搭建。下面这段可以直接渲染:
```json
"custom_elements": {
"lamp-post": { "theme": "custom", "names": ["路灯"], "h": 1000, "w": 300, "real": 4, "parts": [
{ "cyl": { "a": [0, 0], "b": [0, -780], "ra": 34, "rb": 20, "dark": 0.2 } },
{ "shape": { "pts": [[-90,-940],[90,-940],[60,-780],[-60,-780]], "tone": 0 } },
{ "solid": { "pts": [[-120,-930],[0,-1000],[120,-930]], "gouge": 0 } }
] },
"ink-stroke": { "theme": "custom", "names": ["墨迹"], "h": 1000, "w": 8000, "real": 0.02, "parts": [
{ "line": { "pts": [[-3650,-260],[-3300,-950],[-2850,-1000],[-3000,-420],[-2500,-330],[-1900,-720],[-1000,-230],[700,-130],[3333,-32]], "w": [80,170,110,180,100,150,110,90,50], "curve": true, "white": true } }
] }
}
```
一律用局部单位:原点在元素底部中央,向上是负 y,`h` 和 `w` 决定大小,再由 `signs[].h` 缩放到页面。
| 图元 | 画什么 | 计入轮廓 |
|---|---|---|
| `cyl {a,b,ra,rb,dark,cap}` | 圆柱形体,排线环绕形体 | 是 |
| `shape {pts,tone,angle,cross,curve}` | 平面排线,`tone` 从 0(白)到 1(黑) | 是 |
| `solid {pts,gouge,curve}` | 带白色刀痕的纯黑 | 是 |
| `ball {c,r,ry,dark}` | 球体或椭球 | 是 |
| `ring {c,ro,ri,tone}` | 中空的环 | 是 |
| `box {x0,y0,x1,y1,d,tone,side}` | 斜视的盒子 | 是 |
| `line {pts,w,white,curve}` | 边缘带刀痕的线 | 是 |
`line.w` 用局部单位,和 `pts` 相同,不是页面像素。可以是一个数字,也可以是每个点一个宽度的列表,让线条有粗细变化。页面上不会细于 5.5 像素。自定义元素可以全部由线条组成,线条计入大小和位置。`white` 线本身就是刻痕,所以没有光晕。
从后往前画。`names` 里只写它真正是的东西。一个自定义元素算一个摆放元素。
先单独看:作为符号放一次常用尺寸,再放一次页面高度的 0.1,都在 600 宽下看,也要看它的外轮廓。`sheet.mjs` 只显示元素库里的元素,所以要看你自己渲染的结果。如果没有标注就可能被认成别的东西,就加上能辨认的特征,或者放弃这个想法。
完整可用的 spec 在 `assets/examples/custom-element.spec.json`。
## 信息不足时
复述你拿到的事实。绝不编造事实、客户、数字或引语。
- **只有标题。** 标题通常有两种读法。说出这两种,能问就问是哪一种,否则选更有力的那种继续。`thesis_source` 设为 `headline`,论点以“暂定论点,仅从标题推断:”开头,并在 `assumptions` 里写明你的理解。完整的 spec 在 `assets/examples/headline-only.spec.json`。
- **论点不清楚。** 如果文章只是报道、罗列或东拉西扯,不要去画它的话题。告诉用户:“我找不到一个明确的主张,最接近的是……”,请对方确认。没人能回答时,用文章结尾所倾向的主张,`thesis_source` 设为 `inferred`,并列出你的假设。如果文章有两个论点,选结尾所主张的那个,另一个写进 `assumptions`。
- **完全没有论点**,比如新闻通知或产品清单:直说,不用本技能做封面,见“不适用的情况”。
- **没人能回答。** 继续做,并在回复和 spec 里列出假设。
- **想要别的方案。** 用被放弃的寓象另写一份 spec,放到新文件夹。要换物件,不只是换 seed。
- **想要别的尺寸。** 本技能只输出 16:9。让用户用自己的工具裁切副本,并说明可能裁掉边框。
- **没有文章链接。** 封面不需要链接。
- **文章没有标题。** 原样用第一句作 `article.title`,并写进 `assumptions`。
## 成套封面
做系列时,每张的主物件、变形和大部分元素都要不同。运行 `node scripts/check.mjs --set 文件夹1 文件夹2 文件夹3`。
## 编辑
`cover.svg` 每个元素一组,带 `data-element` 和 `data-role`。编辑时只用黑白填充,然后运行 `node scripts/export-svg.mjs cover` 并重新检查。PNG 与 SVG 对不上就过不了检查,事后贴上去的标题就是这样被发现的。
## 交付前检查
- [ ] 论点是一句有人会反对的话,或已标明出于推断。
- [ ] 考虑过三个寓象,放弃的两个有理由,选定的一个用一句话说清。
- [ ] 通过互换检验:这张图不适用于相反的论点。
- [ ] 一个物件,一种变形,最多三个辅助符号,摆放元素不超过 4 个。
- [ ] 冷读是看图后、看说明前写的,并且对上了论点。
- [ ] 每个元素都名副其实,没有近似替代。
- [ ] 在本技能文件夹运行 `node scripts/check.mjs`,退出码为 0。
- [ ] 亲眼看过 1200 宽和 600 宽,一眼能读出一个想法。
- [ ] 画面没有文字,说明只用一种语言。
- [ ] 虚构内容已标注,没有编造任何内容。
## 不适用的情况
- 封面必须带标题、标志或价格。请在图外添加,或用其他技能包。
- 文章没有论点,比如通知、日程或更新日志。
- 需要照片、真人肖像,或需要准确呈现真实地点和产品。
- 需要彩色或品牌色。
- 题材不适合奇异的寓象,比如新近的丧亲或灾难。
## 运行要求
只需要 Node.js 18 或更高版本。如果要靠读 `assets/` 源码才能弄明白,那是本技能的缺陷,你不应该需要这样做。完整渲染一张不到一秒,`check.mjs` 也不到一秒。不用浏览器,不联网,不用图像模型。不需要 Playwright;如果想自己在浏览器里对比 SVG,可运行 `npm install playwright`,必要时设置 `NODE_PATH`。交付的每张封面都要亲眼看过。
风格参数见 `references/style.md`,元素库见 `references/elements.md`,外观见 `references/element-sheet.png`。外观图没有文字标注,因为本技能包不绘制文字;对应的行和列见表格。查看指定元素:`node scripts/sheet.mjs out.png --px 220 --only key,padlock`,加 `--sil` 可看外轮廓。外轮廓认不出来的元素,缩小后也读不出。标为“靠内部”的元素,在只保留轮廓的操作里会被拒绝。



