# Whiteboard Stream Animation

> 将文章、分镜或现有彩色图片制作成流式笔迹白板动画视频：没有源图时先输出配图策略、经用户确认后生成统一风格源图；有源图时直接渲染。笔尖沿连续轨迹滑行落墨，分起笔(线稿)、添彩(还原原色)、凝视(停留)三段，带手部/笔尖覆盖，输出 MP4。与逐格跳变的做法不同，本 skill 的笔迹是连贯流动的。当用户说"流式手绘"、"笔迹动画"、"白板流式动画"、"把图片画成视频"、"手绘笔迹"时触发。

- Skill: `geeklee/whiteboard-stream-animation` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add geeklee/whiteboard-stream-animation`
- Raw SKILL.md: https://api.skillmd.com/api/skills/geeklee/whiteboard-stream-animation/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: geeklee (https://skillmd.com/u/geeklee)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/geeklee/whiteboard-stream-animation

---


# 流式笔迹动画生成器

将文章或分镜生成的统一风格源图，或用户直接提供的一张彩色图片，渲染成白板手绘动画。核心特征：**笔尖沿一条连续的笔迹滑行，边走边落墨**，而不是一格一格地跳变揭墨。

动画分三段：

1. **起笔 (ink)** — 笔尖沿墨迹流铺下黑白线稿
2. **添彩 (color)** — 笔尖沿同一条轨迹回头，用原色墨刷把画面点亮，还原为原图
3. **凝视 (gaze)** — 收笔后停留若干秒，展示完整原图

支持**单图模式**与**队列(批量)模式**两种。

---

## 前置生图模式：从文章或分镜生成源图

当用户提供文章、口播稿或分镜，但尚未提供可渲染图片时，必须先完成本阶段，再进入下方的单图或队列模式。所有面向用户的说明、配图策略和文件名说明使用中文。

### 统一出图视觉规范（强制）

所有场景的源图必须遵循同一套视觉语言；在生成图片前，将以下要求完整写入出图提示词，并在生成后检查是否满足：

- **风格与构图：** 极简手绘插图、纯素描草图风格、类似 Notion 的克制涂鸦美学。以概念表达为主，不追求写实；构图简洁、背景干净、大量留白，整体情感平和、清晰，系列内的线条、人物和配色保持一致。
- **颜色与材质：** 使用米色纸张背景 `#F5EBD7`、深灰色草图线条；仅可用橙色 `#FFA500` 作为少量概念性点缀色。不得使用其他强调色、高饱和度配色或复杂纹理。
- **人物与对象：** 人物统一使用无脸圆形头的人像；对象以简洁轮廓、少量线条和留白表达，强调关系、变化或核心概念，而非真实比例、材质与细节。
- **绝对禁止：** 任何文字、词语、字母、数字、字体或标签；写实感、摄影细节、3D 效果、绘画质感；复杂场景、密集背景、繁复装饰和高饱和度画面。

### 工作流程

1. 阅读文章或分镜，先输出配图策略，不生成图片。每幕只表达一个核心意思，建议每张图承载 25–35 秒口播；策略应包含场景编号、核心表达、画面主体与对应口播段落。
2. 等待用户确认配图策略。未确认前不得生成图片，也不得开始渲染视频。
3. 确认后，按“统一出图视觉规范”逐幕生成 16:9 暖米黄色旧纸张底线稿图。背景使用 `#F5EBD7`，主体之间保留充足留白，便于自动拆分；不得生成文字、复杂照片、重叠对象或与该规范冲突的视觉元素。
4. 实际查看每张生成图，确认其无文字、主体清晰、留白充分且整组风格一致。发现不符合规范时先重新生成该图。
5. 将通过检查的图片保存到用户项目的 `assets/whiteboard/<项目名>/`；单图进入单图模式，多幕图片连同对应时长进入队列模式。

建议命名：`scene-01-<名称>.png`、`scene-02-<名称>.png`。生成的线稿图是后续流式笔迹渲染的唯一源图；不得在渲染时以未检查的草稿图替代。

多幕场景默认进入队列模式；若用户希望把各幕串成一条完整视频，用队列模式的 `--merge`（详见下方队列模式第三步）。

---

## 模式判定

- 用户提供**单个图片路径** → 单图模式
- 用户提供**多张图片路径 + 对应时长**（两个数组）→ 队列模式
  - 只要各幕的独立视频 → 队列默认行为
  - 要把各幕串成一条完整视频 → 队列模式加 `--merge`（单片仍保留，另出一个合并总视频）
- 用户提供**文章、口播稿或分镜，且未提供图片** → 前置生图模式；用户确认配图策略并完成生图检查后，按生成图片数量转入单图或队列模式

---

## 单图模式工作流

### 第一步：准备环境

先用 `--check` 探测环境是否就绪：

```bash
python <skill目录>/scripts/prepare_env.py --check
```

- 成功（退出码 0）：末行输出 `ENV_PY=<解释器路径>`，**捕获该路径供后续步骤使用**，直接进入第二步
- 失败（退出码 1）：执行完整安装：

```bash
python <skill目录>/scripts/prepare_env.py
```

安装脚本会在 skill 目录下建立 `.venv` 虚拟环境并补齐缺失依赖（`opencv-python`、`numpy`、`av`(PyAV，用于纯 pip 的 H.264 转码)），末行同样输出 `ENV_PY=<路径>`。

### 第二步：确认输入图片

从用户请求中取图片路径并确认文件存在。支持格式：PNG、JPG、JPEG、BMP、TIFF。白色或浅色背景的图效果最好。

### 第三步：确定参数

可选参数都有合理默认值：

| 参数 | 标志 | 默认值 | 说明 |
|------|------|--------|------|
| 图片路径 | 位置参数（必填） | — | 输入彩色图片 |
| 输出目录 | `--out-dir` | `./out` | 视频输出目录 |
| 总时长 | `--total-ms` | `10000` | 视频总时长（毫秒） |
| 关闭覆盖 | `--bare-tip` | 默认开启手部覆盖 | 不叠加笔尖/手部 |
| 自定义笔尖 | `--pen-image` | 内置 `drawing-hand.png` | 替换手部素材 |
| 上色风格 | `--color-fill` | `contour-wipe` | 添彩阶段画法：`contour-wipe` 轮廓感知自上而下扫描（默认）；`brush` 沿笔画轨迹刷 |
| 停顿节奏 | `--pause` | `heavy` | 起笔段换笔呼吸：`heavy` 明显（默认）；`auto` 按密度自动分档；`off` 关闭；`light` 少量 |
| 笔迹路径 | `--ink-path` | `grid` | 起笔段笔迹：`grid` 网格格中心插值（默认）；`skeleton` 骨架级像素追踪（更精准贴合线条） |

### 第四步：运行渲染脚本

用第一步拿到的 `ENV_PY` 运行：

```bash
<ENV_PY> <skill目录>/scripts/stream_render.py <图片路径> [--out-dir <目录>] [--total-ms <毫秒>] [其它可选参数]
```

默认配置已是最优组合（grid 笔迹 + contour-wipe 上色 + heavy 停顿），通常只需指定图片路径和时长：

```bash
<ENV_PY> <skill目录>/scripts/stream_render.py /path/to/photo.png --out-dir ./out --total-ms 12000
```

### 第五步：返回结果

脚本会把最终视频路径打印到 stdout（末行形如 `OUTPUT=<路径>`），把该路径告知用户。输出文件命名格式：`stream_YYYYMMDD_HHMMSS_h264.mp4`。

---

## 队列(批量)模式工作流

当用户提供图片路径数组 + 对应时长数组时使用。

### 第一步：准备环境

与单图模式相同，先跑 `prepare_env.py` 取 `ENV_PY`。

### 第二步：校验输入

从用户请求中获取：

- **图片路径数组**（必填）
- **时长数组**（毫秒，必填，与图片一一对应）

**必须满足**：两数组长度相同；每张图都存在；每个时长为正整数。

### 第三步：运行队列渲染脚本

```bash
<ENV_PY> <skill目录>/scripts/queue_render.py \
  --images /p/img1.png /p/img2.png /p/img3.png \
  --durations 10000 15000 8000 \
  [--out-dir ./out] [--bare-tip] [--pen-image <路径>] [--fail-fast] \
  [--merge] [--merged-name <文件名>]
```

- `--fail-fast` 可选：某个任务失败立即中止整批；不加则失败不阻塞后续。
- `--merge` 可选：全部渲染完后，把各成功片段**按输入顺序硬切合并**为一条总视频；**单片仍保留**，另在输出目录生成合并视频。合并优先走系统 ffmpeg 无损拼接（`-c copy`，不重编码）；片段尺寸不一致或无 ffmpeg 时自动重编码（ffmpeg filter 或 PyAV）。默认文件名 `merged_YYYYMMDD_HHMMSS.mp4`，可用 `--merged-name` 指定。
  - 提示：要无损合并，各幕应统一 16:9、同一渲染参数（默认即满足）；尺寸混用会触发重编码并缩放补边到第一段尺寸。

脚本内部串行调用 `stream_render.py`，逐个打印进度；开启 `--merge` 时末行输出 `MERGED=<合并视频路径>`。

### 第四步：返回结果

告知用户：生成总数、成功/失败数、输出目录；若有失败则列出失败图片。开启 `--merge` 时，额外告知合并视频路径（脚本末行 `MERGED=`）。

---

## 三种模式与常用组合

三个独立维度控制动画风格，各有默认值，默认组合已是推荐配置：

| 维度 | 标志 | 选项 | 默认 | 说明 |
|------|------|------|------|------|
| **笔迹路径** | `--ink-path` | `grid` / `skeleton` | `grid` | 起笔段笔尖轨迹：`grid` 沿网格格中心插值（块状感、稳定）；`skeleton` 沿骨架像素追踪（细线条、精准贴合原图、交叉点无碎笔画） |
| **上色风格** | `--color-fill` | `contour-wipe` / `brush` | `contour-wipe` | 添彩段画法：`contour-wipe` 颜色自上而下沿轮廓蔓延（涂色覆盖感）；`brush` 沿笔画轨迹逐点刷原色（手绘涂色感） |
| **停顿节奏** | `--pause` | `heavy` / `auto` / `light` / `off` | `heavy` | 起笔段换笔呼吸：`heavy` 明显停顿；`auto` 按密度自动；`light` 少量；`off` 关闭 |

### 常用组合

```bash
# 默认推荐（不传参即等同此配置）：grid + contour-wipe + heavy
<ENV_PY> <skill目录>/scripts/stream_render.py photo.png --total-ms 12000

# 最强画质：骨架追踪 + 轮廓上色 + 明显停顿
<ENV_PY> <skill目录>/scripts/stream_render.py photo.png --ink-path skeleton --color-fill contour-wipe --pause heavy

# 快速生成（关停顿、网格笔迹、沿轨迹上色）
<ENV_PY> <skill目录>/scripts/stream_render.py photo.png --pause off --color-fill brush

# 只要骨架追踪的精准笔迹，其余默认
<ENV_PY> <skill目录>/scripts/stream_render.py photo.png --ink-path skeleton
```

> 提示：`skeleton` 笔迹对线稿清晰的图（插画、简笔画）效果最好；照片或背景复杂的图用默认 `grid` 更稳定。

---

## 进阶调参（通常不需要）

`stream_render.py` 还接受几个覆盖默认值的旋钮：`--fps`（帧率，默认 60）、`--grid-edge`（网格边长，默认 10）、`--brush-radius`（墨刷半径，默认 40，仅 brush 模式）。仅当用户明确要调整画质/体积时使用。

`contour-wipe` 上色模式（默认）另有几个旋钮：`--wipe-decay`（阻力场向下衰减系数，默认 0.86，越小越快越过轮廓）、`--wipe-delay-ratio`（轮廓处前沿扣减比例×h，默认 0.04，越大轮廓处停留越久）、`--wipe-blocks`（笔尖横向来回趟数，默认 18）。

`skeleton` 笔迹模式的碎片过滤阈值固定为 8 个采样点（骨架笔画短于此即丢弃），无对应 CLI 参数，如需调整改 `Config.skeleton_min_points`。

起笔段停顿由 `--pause` 控制（默认 `heavy` 明显停顿）。若改 `--pause auto` 则按"每格帧数"自动分三档——内容稀疏时多停顿、密集时不停顿。

---

## 故障排除

- **`ModuleNotFoundError`**：重跑 `prepare_env.py` 补依赖。
- **`无法读取图片`**：确认路径正确、文件非损坏；带中文/空格的路径建议加引号。
- **没有 H.264 输出、只有 mp4v**：系统 ffmpeg 与 PyAV 都不可用时才会发生，脚本保留原始 mp4v 编码并给出 warning。正常情况下 `prepare_env.py` 已装好 PyAV，无系统 ffmpeg 也能得到 H.264；若仍是 mp4v，重跑 `prepare_env.py` 确认 `av` 安装成功，或安装系统 ffmpeg（体积更优）。
- **队列模式单个任务失败**：默认不影响后续任务，最终汇总会列出失败项；如需遇错即止，加 `--fail-fast`。

