Skip to content

Repository files navigation

Spine AI Generator

English | 中文

把一张 2D 立绘自动拆成部件、生成骨架、导出成 Spine 工程的本地工具。

上传一张图 → AI 判断有哪些部件、谁压着谁 → 像素级切图 → 生成骨骼层级 → 一键导出成 目标平台的 Spine 资源(Cocos / Unity / Spine 编辑器各版本),外加一个能直接进 Spine 编辑器二次编辑的 .spine 工程。

看板演示:部件拼装预览、骨骼层级、idle 动画播放


目录


这是什么

做 2D 游戏(尤其是带骨骼动画的角色)时,美术把一张立绘手工拆成头、身体、手臂、配饰……再 在 Spine 里建骨骼、绑权重、调绘制顺序,是个重复且耗时的活。这个工具把这段自动化:

步骤 手工做 这个工具
拆部件 抠图软件里一块块抠 AI 判断部件清单 + 像素级分割
定层级 逐个想谁是谁的父级 按遮挡关系自动推断
建骨骼 手动摆放、对旋转中心 从部件 bbox 和姿态推出 pivot
做网格 沿接缝手动连线刷权重 栅格剖分 + 环带缝合,接缝共享权重
补遮挡 手工仿制图章补被压住的部分 图像生成模型按上下文补图
导出 逐个骨架/图集配置 一键出多目标格式

它不是"一键出成品动画",它产出的是一个干净、可继续编辑的工程起点:部件分好了、 层级建好了、权重刷好了,美术拿到手是接着调网格和 K 帧,而不是从空白开始。

质量取决于源图。角色立绘(部件边界清晰、遮挡关系明确)效果最好; 部件互相穿插得很碎、或大量半透明的图,需要人工收尾。


技术实现流程

每个阶段都有自己的质量门:过不了就在阶段内重试,不把烂结果往下游传。

原始图片
   │
   ▼
阶段 0:场景理解                                    视觉模型
   │  ├─ 有哪些部件、谁压着谁
   │  ├─ BBox(粗定位)/ Pivot(关节)
   │  ├─ Parent(层级)/ Depth(绘制顺序)
   │  └─ 多边形轮廓(可选,SAM 的回退路径用)
   │        │
   │   JSON 被截断(stop_reason=max_tokens)→ 加大 token 重来一次
   ▼
阶段 1:切图 / 分层                                 MobileSAM(可选)
   │  ├─ 把 BBox 当 prompt 喂给 SAM → 逐像素 Mask
   │  │     没装 SAM 就退回阶段 0 给的多边形,流程不中断
   │  ├─ 掩码唯一归属:重叠像素归 depth 最大者
   │  ├─ 掩码夹回自己的框内(防小配件擦掉大部件)
   │  ├─ 无主像素按连通性认领,并撑开窗口
   │  ├─ 导出 RGBA 图 + 边缘扩散
   │  └─ 写 .erased.png:被本部件遮挡的真实像素(阶段 2 的真值)
   │        │
   │   对齐诊断 → 写进生成日志,不自动重切
   ▼
阶段 2:遮挡补图                                    图像生成模型(可选)
   │  ├─ 被压住的地方在切图上是透明的洞
   │  ├─ 补全遮挡区域 / 修复边缘 / 保持画风一致
   │  ├─ 被盖住的那片直接贴 .erased.png 真值,不让模型照着遮挡者再画
   │  └─ 单轮接口失败 → 退避重试 3 次(只重试临时故障码)
   │        │
   │   孔洞守卫按像素数补砸比例(近白/近黑/中暗色填充 = 补砸)
   │   ┌────┴────┐
   │   │         │
   │  > 2%    ≤ 2%,或已跑满 2 轮
   │   │         │
   │   ▼         ▼
   │ 重补一轮   留最好的那一轮(不是最后一轮)
   │(从原始切图重来,不在补砸结果上接着补)
   ▼
阶段 3:生成骨骼
   │  ├─ Bone:拓扑序 + 一根合成 root(Spine 编辑器只认单根)
   │  ├─ Mesh:栅格剖分 + 环带缝合
   │  ├─ Weight:接缝两侧共享权重,每顶点 ≤ 4 根骨骼
   │  ├─ Pivot → 骨骼原点,像素坐标 → Spine 坐标(居中、Y 翻转)
   │  └─ Slot 按 depth 排序 = 绘制顺序
   ▼
阶段 4:动画 + 导出
   │  ├─ 生成 idle(幅度压在 1.5° 内,转多了接缝会露)
   │  ├─ 按目标平台转格式:Cocos / Unity / Spine 4.0–4.2
   │  │     版本差异:3.8 用 angle、4.0+ 用 value;skins 一个是对象一个是数组
   │  ├─ 打图集、权重内联进 vertices 流
   │  └─ 调 Spine 编辑器 CLI 生成 .spine
   │        │
   │   ┌────┴────┐
   │   │         │
   │ CLI 拒绝   成功
   │   │         │
   │   ▼         ▼
   │ 错误写进   产物落盘
   │ README.txt  (见「导出产物结构」)
   │   │         │
   │   └────┬────┘
   ▼        ▼
在预览区看拼装与 idle → 导出 Spine 资源

一句话概括每一步在解决什么

阶段 解决的问题 不做会怎样 质量门
0 场景理解 图里有哪些部件、谁压着谁 不知道该切成几块 JSON 截断就重来
1 切图 / 分层 每个部件的精确像素边界 切图互相重叠,转动时穿插 对齐诊断写日志
2 遮挡补图 被压住的区域是空的 部件一转就露洞 补砸比例 > 2% 重补
3 生成骨骼 层级、旋转中心、绘制顺序、接缝权重 动起来全乱、接缝裂开 纯计算,无门
4 动画 + 导出 变成目标平台能加载的格式 进不了项目 Spine CLI 拒绝就报错

底板与孔洞兜底(_base_plate + 补图守卫)贯穿阶段 2:拼不上的缝由整图尺寸的底板遮住, 近白/近黑/中暗色的填充判定为补砸并换成邻域真值——不做就是底板黑块和切图白点。


最小可用范围

核心流程只需要 Node + 一个 API Key,其余全是可选增强:

功能 需要什么 不要它会怎样
AI 分析部件 必需:一个视觉模型 API Key 工具无法工作
切图 / 拼装 / 骨架 / 导出 必需:Node 20+ 工具无法工作
像素级分割 可选:MobileSAM(约 800MB)或 SAM 3(约 4GB) 回退到多边形蒙版,边界略糙但能用
遮挡补图 可选:一个图像生成模型 被压住的区域留透明,部件单独看有洞
.spine 源工程 可选:本机装了 Spine 4.x 编辑器 目标平台资源照常产出,只是没有可二次编辑的工程

也就是说:npm install + 填 API Key 就能跑出目标平台能直接加载的资源。剩下三项按需再装, 任意一项缺失都只影响对应的那一个产出,不会让整条流程失败。


快速开始

# 1. 依赖
npm install

# 2. 配置 API(二选一)
cp .env.example .env
#   然后编辑 .env,填 ANTHROPIC_API_KEY
#   用自建网关/中转服务的,再填 ANTHROPIC_BASE_URL
#   也可以不建 .env,直接在网页界面里填

# 3. 启动
npm run web
# → http://localhost:3000

无需任何 Python 环境、无需 Spine 编辑器即可产出可用工程。

可选增强(按需):

# 像素级分割:自动建虚拟环境 + 拉模型权重(约 800MB,一次性)
npm run sam:setup && npm run sam:check

# 或者换成 SAM 3(约 4GB,需要 Python 3.10+):
#   npm run sam3:setup && npm run sam3:check
#   然后在 .env 里设 SPINE_SEGMENTER=sam3

# .spine 源工程:装好 Spine 4.x 编辑器即可,会自动找常见安装位置
# 装在别处就设 SPINE_CLI_PATH

两个分割器怎么选:

MobileSAM(默认) SAM 3
提示方式 框(bbox) 文本(部件名)
速度 每部件 10~25ms 每部件约 4.5s
环境大小 585MB 4GB(含 3.4GB 权重)
Python 3.9 3.10+
擅长 大块部件 细碎部件(眼镜、眼睛、耳环)

MobileSAM 只吃框,而框里几乎总装着好几件东西,它只挑最显眼的那件——实测 眼镜的框里它挑中整张脸。SAM 3 用文本提示绕开这个问题,给 glasses 就是眼镜。

所以换 sam3 是为了治具体的病,不是普遍升级:默认保持 mobilesam,只在 细碎部件被切错时切过去。两台环境互不影响,可以都装、随时切。

网页「5. 网格与补图」里有对应的单选控件,点了立刻生效(不用重启),并写回 .env 让下次启动还记得。没装的那个会自动置灰并显示安装命令。

SAM 3 权重是 SAM License(不是本项目的 Apache-2.0),官方仓库在 HuggingFace 上是需要审批的 gated 仓库。安装脚本只从 ModelScope 镜像拉到 你自己机器上、不随仓库分发,用之前请自行确认许可条款。


使用流程

# 在界面上做什么 背后发生什么
1 上传立绘 PNG 读出尺寸,建立像素坐标系
2 输入提示词,描述部件结构与旋转中心 提示词质量直接决定部件表质量,见下
3 选目标平台(Cocos 3.8 / Unity / Spine 4.0–4.2) 决定骨架版本号、旋转字段名和 skins 形状
4 点「生成」 走阶段 0→3,日志面板实时输出
5 在预览区看拼装结果、切播放看 idle 动画 有缝/有异色就能立刻发现
6 点「导出」 走阶段 4,产出目标平台资源 + .spine

提示词怎么写

工具自带四类提示词模板(角色 / 道具 / 特效 / 物品),在界面上点「2. 提示词」旁的 设置按钮可以改,模板存在 config/prompt-templates.json。

写提示词的关键是描述结构和旋转中心,而不是描述画面内容:

✅ 好的写法
   一个女角色,左手叉腰、右手拿剪刀。
   包含:头、发髻、眼镜、身体、围裙、左臂、右臂(含剪刀)、鞋。
   头部绕脖子旋转;手臂绕肩膀旋转;围裙绕腰部旋转。
   绘制顺序:身体 → 围裙 → 手臂 → 头 → 发髻 → 眼镜。

❌ 差的写法
   一个生气的女人
   (没说有哪些部件、没说层级、没说旋转中心)

内置模板

四套模板都在 config/prompt-templates.json,界面上可改。它们管的不是「画什么」, 而是怎么拆、怎么定父子、pivot 放哪:

模板 拆解思路 pivot 规则 部件数
角色类 躯干为根;服装按由内到外分层;手与手持道具必须合并(分开必定缺块) 头在颈部底端、上臂在肩、前臂在肘、手在腕 6~15
道具类 主体为根;按真实运动拆(能转的轮子、能扣的扳机) 放在真实旋转轴上 4~10
特效类 按距离核心的远近分层,最外层画在最上 基本都在几何中心,缩放/旋转时向外扩散才自然 3~8
物品类 只拆需要动的部分,纯装饰的整体一个部件 铰链/转轴位置 1~5

三套规则在四类模板里是共通的,写在模板正文里:

  • 层级:口诀「盖人的当儿子,被盖的当父亲」——被遮住的当父级(先画),遮人的当子级(后画)
  • bbox 外扩:边缘比可见内容再外扩 3~5 px 把轮廓线包进来,宁可多框 5 px 不少框 1 px
  • pivot:写在真实的关节上,不是部件的几何中心

一组实测参数

下面这组是仓库里 test_assets/12.png 跑完整条流程用的配置,界面上每个字段都对应得到:

项 值
分析模型 claude-opus-5(视觉模型,出部件表)
提示词模板 物品类——「好漂亮的水果拼盘」
补图模型 gpt-image-2(同步接口,可带 mask 传本地图)
像素级分割 MobileSAM,权重约 40 MB
网格粒度 8(每个部件的栅格剖分密度)
输出目录 ./output/generated
导出目标 cocos-3.8(骨架 3.8.75,旋转字段用 angle)
产物 7 个部件 → 5 个加权网格 + 2 个 region;图集 1024×436
动画 只有 idle

gpt-image-2 是网关侧的模型码,不是我们要绑定的东西——换服务商时它和白名单 一起在界面上重选,config/api-defaults.json 里只放接入点地址。


导出产物结构

output/<工程名>/
│
├── <输入图名>_temp/                    ← 中间产物,重跑补图要用,导出不会清掉
│   └── Image/
│       ├── <部件>.png                  切图
│       ├── <部件>.erased.png           被遮挡区域的真实像素(补图真值)
│       ├── <部件>.front.png            该部件在别人前面的部分
│       └── verify-input.json           校验用输入快照
│
└── <输入图名>/
    ├── Spine工程/
    │   └── <输入图名>.spine            ← 可直接用 Spine 编辑器打开,二次编辑用
    │
    └── <目标格式>/                      cocos-3.8 / unity / spine-4.2 ...
        └── <输入图名>/
            ├── <输入图名>.json         骨架
            ├── <输入图名>.atlas        图集描述
            ├── <输入图名>.png          图集页
            ├── images/                 散图(回编辑器改网格时用)
            └── README.txt              这次导出的参数与结果摘要

为什么中间产物单独放 _temp/:补图重跑、重新切图都要读它,导出时清掉就得重跑一遍 昂贵的 AI 流程。每个导出目标各占一层目录,是因为 3.8 和 4.x 的骨架/图集格式互不兼容, 平铺会互相覆盖——重导 Cocos 时 Unity 那份原封不动。


技术栈

层 用了什么 为什么
运行时 Node.js 20+(ESM) 全程无构建步骤,改完直接跑
Web 服务 Express + SSE SSE 推日志流,流水线进度实时可见
图像处理 sharp 原生 libvips,切图/拼装/合成都是毫秒级
视觉理解 Claude 视觉模型 要它输出结构化 JSON(部件表),不只是描述画面
遮挡补图 图像生成模型(可选) 补被压住的区域
像素级分割 MobileSAM(可选,Python) bbox 当 prompt 出精确掩码
编辑器交互 Spine CLI(可选) .spine 是私有二进制格式,只能由官方 CLI 生成
浏览器测试 Playwright(dev) 界面回归测试
前端 原生 JS,无框架 单页面工具,上框架是负担

设计上的几个取舍

为什么不用 SAM 硬撑着,而是留一条多边形回退路径:SAM 要装 800MB 的 Python 环境, 很多人只想先看看效果。回退路径用 AI 直接给的多边形,精度差一点但零依赖, 让人在决定要不要装之前就能跑通全流程。

为什么 .spine 不自己生成:它是 Spine 私有的二进制工程格式(raw-deflate 包裹标记流), 没有公开规范,各 4.x 小版本之间都会变。照着反推写一份,编辑器升级就静默读坏—— 比不产出更糟。所以走官方支持的 CLI。

为什么用 SSE 而不是 WebSocket:日志是单向的,SSE 够用且自带重连,少一层握手。


配置

所有配置项在 .env(参考 .env.example,已 gitignore)。

变量 默认 说明
ANTHROPIC_API_KEY 空 API Key,必填(也可在界面里填)
ANTHROPIC_BASE_URL 空 留空直连 Anthropic 官方;用自建网关/中转服务就填它的地址
PORT 3000 监听端口
OUTPUT_DIR ./output 产物根目录
SPINE_CLI_PATH 自动查找 Spine 编辑器可执行文件
SPINE_SAM_HOME ~/.spine-tool/mobilesam MobileSAM 环境位置
SPINE_SAM3_HOME ~/.spine-tool/sam3 SAM 3 环境位置
SPINE_SEGMENTER mobilesam 用哪个分割器:mobilesam / sam3

换 API 接入点:改 config/api-defaults.json 一处即可——界面表单的默认值从那里取, 不用在代码里翻找。.env 里的设置优先级更高,只影响本机。


常见问题

Q: 需要联网吗? 分析、补图、分割都要调模型,需要联网。切图、拼装、骨架生成、导出全在本地。

Q: 不装 MobileSAM 能用吗? 能。会自动回退到多边形蒙版,边界精度低一些,但流程完整。想对比效果可以先不装跑一遍。

Q: 生成的部件被切坏了 / 有黑块白点怎么办? 先看日志面板里有没有补图失败的记录;「重跑补图」按钮可以只重跑失败的那些。 补图守卫会把近白、近黑、中暗色的填充判定为补砸并替换成邻域真值。

Q: 生成的骨架缺件 / 层级不对? 绝大多数是提示词的问题——回到第 2 步把部件清单、层级、旋转中心写清楚再生成。 也可以直接在界面上改提示词模板。

Q: 能在 Spine 里直接打开导出结果吗? .json 是导入进 Spine(新建工程再导入),.spine 才是打开。 两者都在导出目录里,.spine 在 Spine工程/ 下。

Q: 支持哪些输入格式? PNG / JPG / WebP。要透明背景的话建议用 PNG。

Q: 为什么会生成 _base_plate 这个部件? 它是整图大小的兜底层,用来遮住部件之间拼不上的细缝。如果不需要,可以在提示词里 要求不要底板,或生成后手动删掉。


文档

文档 内容
Web 服务用法 界面各步骤详解、提示词技巧、环境变量
背景移除与补图 补图流程的完整技术细节与踩坑记录
基于深度的擦除 部件隔离为什么按 depth 决定归属
MobileSAM 可行性验证 为什么选 MobileSAM、实测数据、提示策略对比

docs/notes/ 下是排查记录,记录某个问题当时是怎么查、怎么量的。想知道某个设计 决定为什么这么定,通常能在那里找到当时的实测数据。


开发

npm install              # 装依赖

npm run web              # 启动服务
npm test                 # 单元测试
npm run test:e2e         # 端到端(真跑 AI,慢)
npm run test:shot        # 界面截图回归
npm run verify           # 校验产物结构
npm run shot             # 截预览图
npm run check            # 环境自检
npm run sam:check        # MobileSAM 环境状态
npm run sam3:setup       # 装 SAM 3(约 4GB)
npm run sam3:check       # SAM 3 环境状态

代码结构

server/
├── index.js              HTTP 路由 + SSE 日志流
├── generate-cli.js       命令行入口
├── ai/
│   ├── claude.js         视觉理解:图 → 部件表
│   ├── models.js         模型清单
│   ├── image-models.js   图像生成模型清单
│   └── api-defaults.js   接入点默认值(读 config/api-defaults.json)
├── api/
│   ├── cutter.js         切图:掩码 → 独立 PNG
│   ├── isolate.js        部件隔离:重叠归属、无主像素认领
│   ├── mesh.js           栅格剖分 + 环带缝合
│   ├── generator.js      骨架与动画生成
│   ├── targets.js        目标格式适配(3.8 / 4.x 形状差异)
│   ├── atlas.js          图集打包
│   ├── spine-project.js  Spine CLI 交互,生成 .spine
│   ├── inpaint.js        遮挡补图
│   ├── background.js     背景移除
│   ├── baseplate.js      底板兜底
│   ├── workspace.js      目录结构(唯一一份落点算法)
│   └── env-file.js       .env 读写
└── sam/                  MobileSAM 集成(可选)
    ├── client.mjs        常驻进程客户端
    ├── worker.py         Python worker
    └── setup.mjs         一键装环境

web/                      前端(原生 JS,无框架)
src/                      独立的 Spine 读写库(JSON/Binary 解析、往返、校验)
scripts/                  工具脚本
docs/                     文档与配图
config/                   prompt-templates.json、api-defaults.json
temp/test/                测试

跑测试

npm test                 # 快,不碰网络
npm run test:e2e         # 慢,真调 API,验证完整链路

src/ 下的 Spine 读写库可以独立使用——它不依赖 server,做骨架格式转换很方便。


License

Apache License 2.0。

第三方组件(MobileSAM、sharp、Playwright 等)不随本仓库分发,装的时候各自从上游拉, 各自的协议见 NOTICE。.spine 是调本机已装的 Spine 编辑器 CLI 生成的, 本仓库不包含也不转发 Spine 编辑器的任何代码。

About

把一张 2D 立绘自动拆成部件、生成骨骼层级与网格权重,一键导出 Cocos Creator / Unity (spine-unity) / Spine 编辑器各版本可直接使用的 Spine 资源。

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages