Back to skills
SKILL.md
Workrally Thumbnail
ASecurity用 WorkRally 画布生图产出 YouTube / B站 / 小红书 / Instagram 的视频封面与缩略图: 概念框架选型 → 人物身份锁定 → 场景组装 → 高清渲染 → 局部微调 → 文字烧制。 当用户说「视频封面」「缩略图」「thumbnail」「片头图」「竖版封面」「前后对比封面」 「MrBeast 那种封面」时命中。 不处理:普通配图、完整视频生产、选题策划、视频剪辑、视频内部的标题卡。
- 45 stars
- 0 votes
- 0 copies
- 0 views
- Added September 23, 2026
Works with
Security analysis
92/100- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 6 files and shows the line behind each finding
npx -y skills add ahang1598/doubao-workbuddy-qwenwork-skills --skill workrally-thumbnail --agent claude-codeAre you the author of Workrally Thumbnail?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ahang1598-workrally-thumbnail)---
name: workrally-thumbnail
version: 0.1.0
description: |
用 WorkRally 画布生图产出 YouTube / B站 / 小红书 / Instagram 的视频封面与缩略图:
概念框架选型 → 人物身份锁定 → 场景组装 → 高清渲染 → 局部微调 → 文字烧制。
当用户说「视频封面」「缩略图」「thumbnail」「片头图」「竖版封面」「前后对比封面」
「MrBeast 那种封面」时命中。
不处理:普通配图、完整视频生产、选题策划、视频剪辑、视频内部的标题卡。
---
# WorkRally 视频封面
封面的完整生产链路:**概念框架 → 人物casting → 场景 → 渲染 → 局部微调 → 文字**。
封面归本 skill 管——不要绕过它直接调 `canvas_generate_image`。
用户给的**参考封面**只用你自己的眼睛分析,抽取结构化字段来驱动提示词,
**永远不要**把它放进 `input_images`。
## 运行约定
先读 `references/workrally-mcp-mapping.md`。要点:
- 生成前调 `canvas_image_model_list` 取模型,**禁止硬编码 model_id**
- 每个变体一次 `canvas_generate_image`,`count: 1`,各自独立提示词
- 提交后按 `task_ids` 逐个 `canvas_get_task` 轮询,间隔 3 秒
- 参考图放 `input_images`(URL 数组),提示词里用「第一张图片 / 第二张图片」按下标引用
- 本地图片先 `upload_file` 拿 URL
- 提示词用中文;图内文字保留用户原文,逐字不改
- 烧字走**本地 shell**,不要找 `sandbox_exec`
## 执行流程(按序执行,带 IF 的步骤条件成立才触发)
### 1. 收集输入 + 选框架
从用户消息里取:场景描述 · 人脸/角色参考图(0–3 张)· 参考封面(只作风格样例,绝不是人脸来源)·
logo · 标题文字与是否烧进图里 · 比例 · 情绪与变体数量。缺的按「字段默认值」补。
读 `references/thumbnail-frameworks.md`,**每个概念都必须制造信息差**;
内部至少构思 5 个跨框架方案,把最强的(可以是组合)带进提示词。
**图内文字闸门(生成前就要定)**:默认**永远是无文字的干净图**。
只有用户**明确**要求才把文字烧进生成——用户给了标题字符串、说了「加文字」「带标题」,
或**点名**要一个带文字的框架。探索框架时顺手选中的带文字框架(社交 UI / 新闻条 / Day 角标 /
地图标注)**不构成**烧字授权,那种概念渲染成无文字版,或者先问一句。
不要从选题或框架推断用户想要文字;拿不准就默认干净版或问一次。
**人物闸门(强制,渲染任何东西之前先跑)**:先定谁在画面里,不要假设,不要拿陌生人顶替,
**永远不要**把「放个人进去」当默认。
- 有人脸照片或角色图 → **默认锁定**:上传拿 URL,放进 `input_images`,
提示词里按「第一张图片」引用并写身份锁(见下)。**绝不**在已提供角色时另造一个人
- 概念里会出现人、但没给人脸图 → **停下来问一次**:
「封面里要放你自己(或某个特定的人)吗?发张正脸照我来锁身份;还是用生成的人物,或者干脆不要人?」
- 批量渲染(如「把所有框架都跑一遍」)时,只要有任一框架是以人为主,**渲染整组之前**问这一次
- 明确说要生成的人物 → 用文字描述(只在明确选择时,绝不静默默认)
- 不要人 → 选无人框架(风景 / 产品 / 图示 / 地图俯瞰)
**变体数量闸门(生成前就要定)**:用户或上游流程已给的数量是已答字段,直接用,不要再问。
否则问一次要单张还是一组变体——默认给约 4 个(同一概念,各自不同情绪和/或镜头),
每个都是独立请求,**不要**用 `count:N`。变体 = 情绪 × 镜头,硬上限 16。
### 2. IF 用户给了参考封面
分析之前先问一次:**贴近这张参考**(默认:尽量保留它的风格、构图与主体)还是**独立发挥**
(只当松散灵感)。此前已经表达过「照着这张做」就是已答,不要重复问。
选「贴近」时提示词要被参考强驱动;参考里若有真人,仍然要求用户提供那个人的正脸照,
不要生成一个陌生人。选「独立发挥」只取松散视觉灵感,自己写主体与构图。
然后用你自己的视觉能力填「参考分析契约」(见下),抽成严格 JSON,再按已定的匹配模式驱动提示词。
字段 → 区块映射:brief→区块2 · subject→区块4 · elements→区块5 · location→区块7 ·
composition→区块8 · background→区块9 · split→步骤5 拆分分支 · emotion + emotion_detail→表情槽。
参考的 `subject` 描述按位置贴到照片人物身上作为其姿态/动作,**它不会新增人**;
`person_count` 超过已附照片数量时,多出来的只有在用户要求时才作为文字描述的路人。
参考**只用眼睛看**,绝不进 `input_images`,绝不发给生成模型。
### 3. IF 有人脸/角色/logo 是本地文件
每个生成输入调一次 `upload_file` 拿 URL。按 CHARACTER 顺序保存人物 URL,logo 单独记。
风格参考封面**不要**上传。
### 4. IF 有 logo 且用户要 3D 版
先用「3D logo 提示词」(见下)单独生成一张:`aspect_ratio: "1:1"`,`resolution: 6`(4K),
`input_images: [2D logo URL]`。等它出结果,主渲染用它的**结果 URL** 作为 logo 参考。
### 5. 组装提示词(每个变体一条)
按「房屋提示词结构」区块 1–11 顺序组装。
- 取舍:区块 1 和 11 恒有。2 — 有场景描述或参考 `brief` 时。
3 — 默认恒有那句无文字声明;TEXT / BAKED UI 变体**只在**用户明确要求文字时触发。
4 — 画面里有任何人或生物时:照片人物各写一条身份锁,文字描述的人物在这里用散文描述
(不要写进区块 5),其散文**也要**以 `表情:<情绪短语>` 结尾。
5 — 有标志性道具,或 KEY ELEMENTS 默认值触发时。6 — 有 logo 时。7 — 已知地点时。
8 和 9 — 恒有(无信息时用默认句)。10 — 画面里有人时;默认平光版,
**只有用户点名了轮廓光颜色**才用彩色轮廓变体。
- `<比例说明>` = 「`<比例>` 画幅」。9:16 追加竖画幅子句;画面无人时说「主体在上三分之二」
而不是「面孔」。
- 表情槽 = 所选情绪预设的**括号描述**(震惊 → `张嘴倒吸气、瞪大眼睛`),
或用户自定义短语原文。参考自带的 `emotion_detail` 句子**只**追加到沿用参考情绪的那些变体上。
- **拆分分支**:只按「拆分画面」里的触发规则触发;`X vs Y` 作为**场景**时仍是一整幅统一画面。
触发时拆分契约**替换**区块 1。
- 变体 = 情绪 × 镜头,硬上限 16;画面无人时表情轴为空,变体 = 镜头。
变体之间**只**差表情短语和/或一条 ALTERNATE TAKE 行。
### 6. 提交
每个变体一条独立提示词、一次独立调用:
```jsonc
canvas_generate_image({
prompt: "<变体提示词>",
model: "<canvas_image_model_list 返回的 model_id>",
aspect_ratio: "16:9",
resolution: 6, // 4K;模型不支持时退到它 resolution_options 的最高档
count: 1,
input_images: ["<人物图URL>", "<logo URL 或 3D logo 结果URL>"],
task_name: "<选题_变体N>"
})
```
`input_images` 顺序:人物在前,logo 在后;为空时省略该字段。
有两个及以上参考图时,提示词**第一行**写位置清单:
```
参考图说明:第一张图片是 CHARACTER 1 的脸部参考;第二张图片是品牌 logo。
```
### 7. 渲染后检查(每张都查)
1. 有人脸/角色参考时,身份与角色设计肉眼可辨地一致
2. 没要求烧字 → 画面里没有多余文字或水印
3. 要求烧字了 → 渲染出的文字与指定字符串**逐字**一致
4. 表情(有主体时)和主视觉元素在**约 120px 宽**下仍然读得出来
失败就用**同一条提示词**重渲,每个变体最多 2 次;仍失败就如实告知,不要闷声交付。
### 8. IF 用户要局部微调
用「局部微调」里的提示词,走图生图:把**选中那张的结果 URL** 作为唯一 `input_images`,
`resolution: 5`(2K)。每次接受的产物成为下一次微调的输入。
WorkRally 没有 Seedream 那样的专用编辑模型,用同一批 Kontext 模型做图生图即可;
关键在提示词必须写明「除此之外每个像素保持不变」。
### 9. 导出与交付
把通过第 7 步的变体都拿出来;用户没选就全给。
没有标题文字 → 直接交付干净图。
有标题文字但**没有**明确要求烧进生成 → 用本地脚本烧一层确定性文字
(路径相对本 skill 目录,按实际安装位置补全):
```bash
node <skill 目录>/scripts/bake_text_overlay.mjs \
--image '<选中那张的结果URL>' \
--text '打工人的春天' \
--style beast --position bottom --case preserve \
--out ./thumbnail.png
```
- 先看图选 `top` / `bottom` / `left` / `right` / `center`,让标题占一块空区且不压脸
- 风格五选一:`beast`(默认)· `fire` · `neon-lime` · `clean-glass` · `marker`
- 中文标题用 `--case preserve`(`upper` 只对西文有意义),2–14 字;西文 2–6 词
- 依赖 Playwright + Chromium:缺失时提示
`npm i -g playwright && npx playwright install chromium`,
装不上就降级——交付干净图或经用户明确同意后改走「烧进生成」,
**不要**把浏览器预览说成已导出的 PNG
- 脚本 `--image` 可直接吃 WorkRally 短链(5 小时有效);产物是本地 PNG,
需要入媒资库时走 `upload_file` + `asset_create`
### 提交前检查清单(任一为否先改提示词)
- [ ] 模型来自 `canvas_image_model_list`,不是写死的名字
- [ ] 区块 1(或其拆分替换)是提示词第一块,区块 11 GRADE 是最后一块
- [ ] 画面里有人 → 布光区块在场 + 每张人脸照片各一条身份锁
- [ ] 参考封面**不在** `input_images` 里
- [ ] 每次调用只渲染一个变体,`count` 恒为 1
- [ ] 没要求烧字 → 提示词里有「画面中没有任何文字、UI 标签或水印。」
### 字段默认值(用户和参考都没给的字段)
- 比例 `16:9` · 镜头 1 个 · 有人时情绪取「震惊」;无人时表情轴为空,变体 = 镜头
- 背景:`大胆浓烈的饱和色场渐变,高对比撞色呼应主体配色,柔和暗角,边缘衰减`
- 构图:`主体渲染得大而强势——胸部以上/中近景,占画面约 40–60%,推到前景、落在三分线上,
相机平视,与背景强分离让主体跳出来,浅景深并带一个前景点缀元素`
- 主视觉元素:用户选题里最具体可画的那个名词,放大、朝镜头飞来——与主体重复时省略
- 地点:省略该区块
## 概念框架
「画什么」这一层在 `references/thumbnail-frameworks.md`:16 个封面框架、信息差原则、
组合方式与真实性法则。在步骤 1 按需读取并选定框架。
大多数框架直接映射到下面的房屋结构;需要图内可读文字的那几个走区块 3 的 BAKED UI 子句。
## 模型与分辨率
| 用途 | 选型 | 参数 |
|---|---|---|
| 主渲染 | 从 `canvas_image_model_list` 里选 `max_input_images` 足够、支持 4K(枚举 6)的一档 | `resolution: 6`,每个变体独立提示词 |
| 2D logo 转 3D | 同上,图生图 | `aspect_ratio: "1:1"`,`resolution: 6` |
| 成品局部微调 | 同上,图生图 | `resolution: 5` |
比例只能用模型列表返回的那些(常见 `21:9` `16:9` `4:3` `2:1` `1:1` `1:2` `3:4` `9:16`)。
**没有 `4:5`**——Instagram 竖版用 `3:4`,需要精确 4:5 时生成后本地 ffmpeg 裁切并告知用户。
## 房屋提示词结构(按此顺序组装)
1. **画幅契约** — `大胆有冲击力的视频封面合成图——海报级、写实、高冲击力,不是灰调的电影剧照,<比例说明>,单幅统一画面——不要分屏、不要对角切分,所有元素在同一个连续镜头里自然融合。` 9:16 追加 `主体构图适配竖画幅,面孔位于上三分之二`。框架 8「图示表达」用干净的图表/图形简报替换本块,并去掉写实与布光区块。
2. **场景简报**(用户描述了确切内容时):`场景简报(必须精确呈现):<文本>。`
3. **文字契约** — 默认:`画面中没有任何文字、UI 标签或水印。` 只有明确要烧字时:`文字:把封面标题文字烧进画面,逐字读作"<TEXT>"——超大、极易读的无衬线字体,带干净描边/发光处理,位置绝不压住主体面部。除此之外没有其他文字,没有水印。` 用户**点名**要带 UI 元素的文字框架(社交 UI / 新闻条 / Day 角标 / 地图标注)时改用:`BAKED UI:一个<通用聊天气泡 / 私信行 / 星级评价卡 / 突发新闻下三分之一条 / DAY N 角标 / 地图标注>,读作"<短文本>",干净的通用平台样式——不要出现真实品牌名、应用名或平台 logo。文字要短且与视频内容相符。` 只是被自动选中的带文字框架改渲无文字版。这是除标题外唯一被许可的可读文字,其余道具一律无字无标识。
4. **主体** — 见下方身份锁。最多 3 个角色,照片人物按位置对应 `input_images` 下标。**主体渲染得大而强势——明确的主角,占画面约 40–60%,胸部以上或中近景,推到前景并与背景干净分离;绝不是缩在下三分之一的小主体,绝不是远景视频截图感。** 以 `所有面孔锐利清晰,作为整幅画面的锚点。` 结尾。
5. **主视觉元素** — 让画面跳出来的标志性道具与特效。
6. **LOGO**(有则写) — 2D:`把参考图里的 logo 原样放进构图——形状、颜色、比例一律不动,干净的 2D 放置在强焦点位,轻微投影以作分离,绝不遮挡主体面部。` 3D:`把参考图里的 3D logo 渲染件作为实体体积物融入场景——光泽立体材质,承接场景的主光与轮廓光,投下柔和接触阴影,合成在强焦点位且不遮脸。`
7. **地点** — 场所、时间、天气、氛围。
8. **构图** — 主体大而占据前景(约 40–60%,胸部以上/中近景)落在三分线,主体与背景强分离;尺度层次、机位角度、纵深分层。
9. **背景处理(融合,不是切分)** — 大胆饱和色场、浓烈渐变、强撞色、质感、虚化、边缘衰减。
10. **布光(有人时强制)** — `标志性视频封面布光——强主光雕刻面部,高光清脆、衰减受控;柔和的梦幻补光提亮阴影带来微妙电影感辉光;明确的背光与发丝光沿头发、肩线和轮廓勾出干净明亮的边缘,把主体从背景中锐利分离。` 彩色轮廓变体:把最后一句换成 `明确的<颜色>背光与发丝光勾出鲜明的彩色轮廓……并带同色系微妙辉光。` 轮廓色板:冰蓝 `#4DA6FF`、霓虹品红 `#FF3DBE`、毒性青柠 `#C8FF2E`、琥珀金 `#FFB63D`、纯白。主光与补光**永不**变色,只改背光与发丝光。
11. **调色** — `鲜明高冲击的调色,高对比,明亮干净的曝光,饱和度高到能从屏幕上跳出来,深黑与亮部分明,清脆有光泽,海报般的冲击力,整体作为一幅画统一。<比例>。` 只有明确要求平静/高级/低饱和/氛围感时才收敛。
## 身份锁(防脸部漂移,每个有照片的人物必写)
软性说法(「保持脸和身份一致」)**不够**,模型会漂。每个带脸部照片的角色写:
> CHARACTER N:第 K 张图片里的那个人——身份锁定:以照片级身份一致度还原这个人——
> 与参考照片相同的骨相、眼型、鼻子、嘴唇、下颌线、肤色、发际线与发质。
> 不要美化、不要与其他面孔平均、不要改造脸部;必须一眼就认得出是同一个人。
> 表情:`<情绪短语>`。
漂移仍会偶发(随机性),处置是重渲,不是道歉。
## 情绪预设(11 种)
**震惊**(张嘴倒吸气、瞪大眼睛)、**亢奋**(狂喜咧嘴、眼里放光)、**恐惧**(惊恐凝视、屏住呼吸)、
**困惑**(挑眉、一脸不解)、**决心**(咬紧下颌、目光如炬)、**得意**(心知肚明的坏笑)、
**魅力**(平静有磁性的注视、眉头放松、极淡的从容微笑——有领袖气场,自信但不具攻击性;
这是平静正向的选项,单用「决心」会显得太硬)、**厌恶**(后仰的嫌弃表情)、
**惊叹**(下巴掉了、眼里闪光)、**暴怒**(呲牙的怒火)、**大笑**(头向后仰)。
表情槽里用的是预设的**括号描述**。用户自定义短语原文替换预设(`表情:<自定义>`)。
用户只给了情绪**数量**没点名时,按此阶梯取前 N 个:震惊 → 亢奋 → 暴怒 → 惊叹 → 大笑 →
恐惧 → 得意 → 魅力 → 困惑 → 决心 → 厌恶。交互式提供情绪选项时,永远带一个自定义项。
## 每种情绪的镜头变化
镜头 1 = 设计好的原始取景(无修饰)。镜头 2–4 各追加一行:
- `ALTERNATE TAKE:改为低角度英雄镜头——相机低于视平线仰拍,主体更具压迫性地耸立,背景透视向上拉伸,场景与布光不变。`
- `ALTERNATE TAKE:极端特写推进——面部与表情占据超过半幅画面,背景压缩成柔和虚化的环境,场景与布光不变。`
- `ALTERNATE TAKE:更宽的动态镜头带轻微荷兰角——环境露出更多,主体偏置在三分线上,画面扫过更强的运动能量,场景与布光不变。`
总变体 = 情绪 × 镜头(硬上限 16),每个变体一条独立提示词、一次独立调用。
## 拆分画面
触发:**只在**用户要求拆分/分栏**布局**时——「分屏」「前后对比」「对决」「并排」——
或参考分析返回了 `split=true`。`X vs Y` 作为**场景**是一整幅画面里出现两个主体,**不拆**。
N = 点名的对手/状态/侧面数量(前后对比与对决默认 2);N=2 → 左右两半,N≥3 → 竖向分栏。
拆分契约**替换**区块 1,并原样携带 `<比例说明>` 与 9:16 竖画幅子句。
把区块 1 换成:`拆分式封面,<比例说明>:画面被干净利落的粗分隔线切成 N 个<左右两半|竖向分栏>,
每个分栏是各自完整的小场景,所有分栏共享统一的高级调色。` 然后**只**追加一句模式句:
- **常规**:`每个分栏呈现故事的一个侧面:<分栏1:描述;分栏2:描述;…>。`
- **前后对比**:`左栏:BEFORE 状态——<描述>。右栏:AFTER 状态——<描述>。同一次转变的两个状态之间视觉反差拉到最大。`
- **对决**:`每个分栏呈现一位对手,像拳赛海报那样布光和取景:<分栏1:A 描述;分栏2:B 描述>。视觉分量对等,跨越分隔线的对抗张力。`
- **自定义**:`<用户逐栏描述>。`
**始终**追加:`分栏之上与之间没有标签、没有说明文字、没有文字、没有数字——对比纯靠视觉传达。
所有分栏作为一幅高级图统一调色。`
## 文字策略
默认:画面里**没有**文字——交付干净渲染图,标题文字用清晰的排版层叠上去
(零生成额度、永远可读)。**只有**用户明确要求时才把文字烧进生成,
生成式文字是兜底而不是默认。
五种成熟叠加风格:**Beast**(Anton 白字 + 厚黑描边 + 投影)、
**Fire**(黄→橙→红渐变 + 深色描边 + 暖光)、**Neon Lime**(`#D4FF3F` + 青柠辉光)、
**Clean Glass**(Inter 800 落在毛玻璃药丸上)、**Marker**(黑色 Anton 落在青柠色线框上)。
完整的 HTML/CSS + canvas 烧制配方(描边/阴影/渐变数值、关键的 `paint-order: stroke fill`、
字体加载后再绘制、4K 导出)在 `references/text-overlay-bake.md`。
可执行实现随本 skill 分发在 `scripts/bake_text_overlay.mjs`(已加中文字体栈与中文断行)。
## 成品局部微调(图生图)
把**成品图的结果 URL** 作为图生图输入,每条微调提示词都必须声明其余部分保持像素级不变。
- **换表情**:`只改变人物的面部表情为:<短语>。身份、脸部结构、头发、姿势、身体、服装、logo、背景、布光与构图全部保持完全不变,像素级忠实——纯表情替换。保持封面布光不变。`
- **换背景**:`只替换背景为:<描述>。主体、面部、身份、姿势、服装、logo 与所有前景元素保持完全不变。重建主体边缘的光线包裹,让新背景的光向、色彩与轮廓光自然衔接——保持封面布光。`
- **背景改色**:`只把背景色调偏向以<颜色>为主。背景的结构、内容与纵深完全保持,只改颜色。重建主体边缘的环境色轻微包裹,但面部的主光与补光保持不变。`
- **轮廓光改色**:`只改变主体上的背光/发丝光(轮廓光)颜色为<短语>——就是勾勒头发、肩线、轮廓的那道亮边。不要改主光与补光;不要改背景、姿势、身份、服装、logo、构图。`
微调可以链式进行,每次产物成为新的输入。
## 3D logo 提示词
> 把参考图里的 2D logo 转成高级 3D logo 渲染件:将 logo 的确切形状挤出为有光泽的立体体积,
> 每一个字形、比例和品牌色都保持精确,高端 CGI 产品渲染质感,柔和影棚反射,
> 细微倒角,边缘清脆,悬浮于干净的深色中性影棚背景上并带柔和接触阴影。
> 居中,留白充足,没有多余文字,没有水印。
它可以后台先跑,最终渲染等它。
## 参考分析契约(视觉 → 场景)
用你自己的视觉能力看那张参考封面,产出**严格 JSON**,键恰好如下、不多不少:
```
brief(一句密集的概念描述), subject(笼统的姿态/动作,绝不写具体身份), elements,
location, composition, background, split(布尔), split_count, person_count(0-3),
emotion(11 个预设之一或 'other'), emotion_detail(一句生动描述,覆盖眼睛、眉毛、嘴、头部角度)
```
参考驱动能量/构图/风格——它**绝不**发给生成模型,**绝不**进 `input_images`;
用户没填的场景字段用「从参考推导」的指令补(如「沿用参考的取景逻辑……」)。
## 常见坑
- 没有 `4:5`。Instagram 竖版用 `3:4`,需要精确比例就本地裁切并告知用户
- 脸会漂(随机性)——每张都要对着人脸参考检查再拿给用户,处置是重渲不是道歉
- 一次提交一个变体:用 `count` 批量会毁掉每变体独立提示词(情绪/镜头各需自己的提示词)
- 最终可读性测试:封面是在侧栏约 120px 宽处竞争的,情绪和主视觉元素在那个尺寸下必须还读得出来;
读不出来是**构图**问题,不是分辨率问题
- 中文标题烧字要用 `--case preserve`,`upper` 只对西文有意义
Files in this skill
- SKILL.md
- agents/openai.yaml
- references/text-overlay-bake.md
- references/thumbnail-frameworks.md
- references/workrally-mcp-mapping.md
- scripts/bake_text_overlay.mjs
Attribution
Comments
Loading comments…