vault backup: 2026-06-03 10:30:42
This commit is contained in:
+38
-23
@@ -1,18 +1,27 @@
|
||||
# 06 — 精灵图处理管线
|
||||
---
|
||||
tags: [image-processing, sprite-sheet, gif, computer-vision, go, algorithm]
|
||||
create time: 2026-06-03 10:25
|
||||
---
|
||||
|
||||
> **一句话概括**:自动精灵图处理管线 — 背景移除 → 投影检测 → 切割 → 对齐 → GIF 预览,将一张 AI 生成的 Sprite Sheet 无缝转化为可用的逐帧动画资源。
|
||||
# 06. 精灵图处理管线
|
||||
|
||||
## 概述
|
||||
|
||||
自动精灵图处理管线 — 背景移除 → 投影检测 → 切割 → 对齐 → GIF 预览,将一张 AI 生成的 Sprite Sheet 无缝转化为可用的逐帧动画资源。
|
||||
|
||||
---
|
||||
|
||||
## 正文
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["🖼️ Input PNG<br/>Sprite Sheet"] --> B["🪄 Background<br/>Removal"]
|
||||
B --> C["📊 Gap<br/>Detection"]
|
||||
C --> D["✂️ Tile<br/>Extract"]
|
||||
D --> E["🔍 Filter<br/>MinFill"]
|
||||
E --> F["📐 Trim<br/>Alpha"]
|
||||
F --> G["🎯 Align<br/>padToLargest"]
|
||||
G --> H["🎬 GIF<br/>Preview"]
|
||||
A["Input PNG"] --> B["Background Removal"]
|
||||
B --> C["Gap Detection"]
|
||||
C --> D["Tile Extract"]
|
||||
D --> E["Filter MinFill"]
|
||||
E --> F["Trim Alpha"]
|
||||
F --> G["Align padToLargest"]
|
||||
G --> H["GIF Preview"]
|
||||
|
||||
style A fill:#e3f2fd,stroke:#1976d2
|
||||
style B fill:#fff3e0,stroke:#f57c00
|
||||
@@ -26,7 +35,7 @@ flowchart LR
|
||||
|
||||
---
|
||||
|
||||
## 📋 处理管线总览
|
||||
## 处理管线总览
|
||||
|
||||
AI 生成的 Sprite Sheet 通常包含白色/绿色背景、不均匀间距和尺寸差异。Gen2D 的精灵图处理管线自动完成从"原始 PNG"到"可用动画帧"的全部转换工作,无需用户手动操作。
|
||||
|
||||
@@ -42,7 +51,7 @@ AI 生成的 Sprite Sheet 通常包含白色/绿色背景、不均匀间距和
|
||||
|
||||
---
|
||||
|
||||
## 🪄 步骤 1:背景移除
|
||||
## 步骤 1:背景移除
|
||||
|
||||
AI 生成的图片通常带有纯色背景,管线支持两种模式:
|
||||
|
||||
@@ -69,11 +78,12 @@ if gDominance > tolerance*255 → 透明化
|
||||
- **GreenTolerance** 默认 0.2,控制绿色检测灵敏度
|
||||
- 适用于绿色背景的 AI 生成图
|
||||
|
||||
> 💡 **设计选择**:两种模式互斥,`Process()` 根据 `opts.WhiteBg` / `opts.GreenScreen` 自动选择。
|
||||
> [!tip] 设计选择
|
||||
> 两种模式互斥,`Process()` 根据 `opts.WhiteBg` / `opts.GreenScreen` 自动选择。
|
||||
|
||||
---
|
||||
|
||||
## 📊 步骤 2:切割策略
|
||||
## 步骤 2:切割策略
|
||||
|
||||
管线提供两种切割方式,根据配置自动切换:
|
||||
|
||||
@@ -90,6 +100,10 @@ if gDominance > tolerance*255 → 透明化
|
||||
- 防止突出物(武器/尾巴)被其他行稀释
|
||||
- 每行段获得独立的列边界,互不干扰
|
||||
|
||||
> [!question] 为什么不用简单的阈值分割?
|
||||
>
|
||||
> 精灵图中的角色往往有复杂轮廓——比如挥舞的剑可能横跨多个帧的位置。如果仅用固定阈值,剑的连续像素会让算法误判为一帧。**按行段独立分析**的思路是把二维问题拆解为多个一维子问题,每个子问题只关心当前行段的内容,从而避免跨行干扰。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A["输入图像"] --> B["全局行投影<br/>检测行间隙"]
|
||||
@@ -124,7 +138,7 @@ flowchart TB
|
||||
|
||||
---
|
||||
|
||||
## 🔍 步骤 3:过滤 — MinFillRatio
|
||||
## 步骤 3:过滤 — MinFillRatio
|
||||
|
||||
切割后的每个 tile 都计算填充率:
|
||||
|
||||
@@ -138,7 +152,7 @@ fillRatio = 非透明像素数 / 总像素数
|
||||
|
||||
---
|
||||
|
||||
## 📐 步骤 4:裁剪 — trimAlpha
|
||||
## 步骤 4:裁剪 — trimAlpha
|
||||
|
||||
对每个 tile 执行透明边框裁剪:
|
||||
|
||||
@@ -148,7 +162,7 @@ fillRatio = 非透明像素数 / 总像素数
|
||||
|
||||
---
|
||||
|
||||
## 🎯 步骤 5:对齐 — padToLargest
|
||||
## 步骤 5:对齐 — padToLargest
|
||||
|
||||
动画播放时,如果每帧尺寸不同且内容未对齐,会导致角色"抖动"。
|
||||
|
||||
@@ -169,7 +183,7 @@ canvasH = maxH * 110% // 最大帧高度 + 10% padding
|
||||
|
||||
---
|
||||
|
||||
## 🎬 GIF Maker
|
||||
## GIF Maker
|
||||
|
||||
`gifmaker.Encode()` 将处理后的帧序列编码为动画 GIF:
|
||||
|
||||
@@ -186,11 +200,12 @@ anim.Disposal = append(anim.Disposal, gif.DisposalBackground)
|
||||
anim.BackgroundIndex = 0 // 透明色
|
||||
```
|
||||
|
||||
> ⚠️ **DisposalBackground 的重要性**:如果不设置此选项,GIF 播放器会在前一帧基础上叠加新帧,产生"残影"效果。
|
||||
> [!warning] DisposalBackground 的重要性
|
||||
> 如果不设置此选项,GIF 播放器会在前一帧基础上叠加新帧,产生"残影"效果。
|
||||
|
||||
---
|
||||
|
||||
## 📦 Options 配置速查
|
||||
## Options 配置速查
|
||||
|
||||
| 参数 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
@@ -207,8 +222,8 @@ anim.BackgroundIndex = 0 // 透明色
|
||||
|
||||
---
|
||||
|
||||
## 🔗 关联文档
|
||||
## 关联文档
|
||||
|
||||
- [← 返回索引](00-index.md)
|
||||
- [05 — 生成管线](05-generation-pipeline.md) — 管线中 SplitSprite 节点的调用方
|
||||
- [08 — SSE 实时推送](08-sse-push.md) — 处理进度的实时推送
|
||||
- [[00-索引]] — 文档导航与架构总览图
|
||||
- [[05-生成管线]] — 管线中 SplitSprite 节点的调用方
|
||||
- [[08-SSE实时推送]] — 处理进度的实时推送
|
||||
|
||||
Reference in New Issue
Block a user