| name | yuelu-xhs |
| description | 小红书图文生成器(代码控图版)。用代码画精确线框 → Playwright 截图 → GPT Image 2 上色 → 输出 1080×1440 成品图。当用户说"/yuelu-xhs"、"做小红书"、"做小红书图文"、"把这篇文章转成小红书"时触发。 |
月鹿小红书图文生成器(yuelu-xhs)
代码控图版:代码画线框 → 截图 → GPT 上色 → 成品图。
布局由代码精确控制,AI 只负责上色加美感——布局不会跑。
何时触发
/yuelu-xhs → 启动小红书图文制作
- "做小红书" / "做小红书图文" / "做小红书轮播图"
- "把这篇文章转成小红书"
- "把 xxx 做成小红书图文"
工作流
Step 1:确认输入
用户给了文章路径/内容 → 读取文章
用户没给 → 询问内容来源(md 文件路径、飞书文档、直接粘贴文案)
同时确认:
- 页数:默认 5 页(封面 + 3 页内容 + 收尾),可调整 3~7 页
- 配色:默认橙色系(#FF6B35),可换其他锚点色
- 素材图:文章目录下是否有截图/成品图可嵌入线框
Step 2:规划内容结构
从文章中提取核心信息,规划每页内容:
Page 01 / 封面 / 标题+副标题+核心视觉
Page 02 / 痛点或背景 / 为什么需要这个方法
Page 03 / 方法或流程 / 核心步骤拆解
Page 04 / 案例或证据 / 实测结果/对比/截图
Page 05 / 收尾 / 核心结论+开源/引导
展示给用户确认,用户说"行"或调整后继续。
Step 3:生成 HTML 线框
在文章目录下创建工作目录:
<文章目录>/xhs-图文/
├── 线框/ ← HTML + 截图 PNG
│ ├── screen1-cover.html
│ ├── screen1-cover.png
│ ├── screen2-xxx.html
│ ├── screen2-xxx.png
│ └── ...
├── 成品/ ← GPT 上色后的最终图
├── 素材/ ← 引用的截图/产品图(可选)
├── render-wireframes.mjs
└── colorize.mjs
每张 HTML 线框的关键规范:
| 项 | 值 |
|---|
| 页面尺寸 | 1080 × 1440(body 固定宽高) |
| 背景色 | #f8f6f2(米白) |
| 锚点色 | 默认 #FF6B35(橙色),可配 |
| 字体 | PingFang SC / Noto Sans SC |
| 标题字号 | 80-96px,font-weight: 300 |
| 正文字号 | 22-30px |
| 内边距 | 72px 80px |
| 页脚 | 底部左右对齐,20px,灰色,页码+署名 |
线框设计原则:
- 每页只讲一个核心点,信息密度适中
- 用数字编号(01/02/03)建立视觉节奏
- 用卡片(白底+橙色左边框)承载要点
- 用黑色底条做总结/转折
- 封面必须有视觉钩子(对比图/大标题/数据)
- 收尾页可选暗色底或保持米白,但要与整套风格一致
- 嵌入的截图/素材图用
<img src="../素材/xxx.png"> 引用
- 容器用固定 height + overflow: hidden,img 用 max-height: 100% + object-fit: contain
常用布局组件:
- 标题区:kicker(橙色小标签)+ 大标题(300 weight)+ 副标题
- 痛点卡片:白底 + 橙色左边框 + 编号 + 标题 + 描述
- 流程时间轴:圆形编号 + 竖线连接 + 步骤描述 + 标签
- 案例卡片:左侧缩略图 + 右侧信息(编号/名称/规格/标签)
- 黑色总结条:全宽黑底 + 白字 + 橙色强调
- 引言区块:上下细线 + 居中大字 + 橙色关键词
- Skill 卡片:橙色图标 + 名称 + 描述 + 右侧标签
Step 4:Playwright 截图
用 render-wireframes.mjs 脚本批量截图:
node <工作目录>/render-wireframes.mjs
脚本逻辑:
- viewport 设 1080×1440
- 遍历线框目录下所有 .html
- 每个文件 goto → waitForTimeout(1000) → screenshot clip 1080×1440
- 输出同名 .png 到线框目录
截图后必须验证:用 Chrome DevTools MCP 或直接 Read 图片检查每张线框的布局是否正确。特别注意:
- 嵌入的图片是否正常显示(不是空框/极小)
- 底部内容是否被截断
- 文字是否溢出
Step 5:GPT Image 2 上色
用 colorize.mjs 脚本并行上色:
node <工作目录>/colorize.mjs
脚本逻辑:
- 读取线框目录下所有 .png
- 并行调用 GPT Image 2 的 /v1/images/edits 接口
- API 配置:
- Prompt 要求:保持完全一样的布局和文字位置,加颜色/质感/光影/装饰
- 强调"Keep all Chinese text exactly as shown"
- 输出到成品目录
上色 prompt 模板:
Transform this wireframe into a polished social media card. Keep the exact same layout, text positions, and structure. Add warm [配色描述] background, subtle textures and shadows for depth. Keep all Chinese text exactly as shown. Style: modern, clean, professional [风格描述] with [锚点色] as accent color.
每张可以根据内容微调 prompt(比如暗色页、有截图的页面)。
上色后处理:
- sips -z 1440 1080 resize 到标准尺寸
- 检查成品效果
Step 6:交付
- 弹出 Finder 展示成品目录
- 报告总页数、输出路径
- 用户在 Finder 按空格预览
- 不满意的页面 → 改线框 HTML → 重新截图 → 重新上色单张
Playwright 依赖
脚本需要 playwright,通过软链接使用全局安装:
mkdir -p node_modules
ln -sf /Users/moondeer/.npm-global/lib/node_modules/playwright node_modules/playwright
改图
如果用户对某页不满意:
- 改布局/文字 → 改对应的线框 HTML → 重新截图 → 重新上色
- 只改上色效果 → 调整 prompt → 重新上色单张
- 不要直接改成品 PNG,所有改动从线框驱动
不该做的事
❌ 不要用旧的 md 切页模式——已废弃
❌ 不要用旧的 JSON+模板卡片模式——已废弃
❌ 不要跳过线框验证——直接上色前必须确认线框正确
❌ 不要让一页放太多信息——每页一个核心点
❌ 不要用 flex:1 撑图片容器——给固定 height
❌ 不要用 width:100% height:100% 在 flex 子元素的 img 上——用 max-height + object-fit
历史踩坑
- img 在 flex 容器里不给固定高度会显示为极小或空框
- GPT Image 2 API 输出 1024×1536,需要 sips resize 到 1080×1440
- API 偶尔超时,脚本需要支持单张重试
- 暗色页(黑底)上色后风格会跟浅色页不一致,尽量全套保持统一色调
- 素材图用相对路径
../素材/xxx.png,Playwright 能正确解析 file:// 协议下的相对路径