明确序列帧去背景处理模式

去背景弹窗要求用户显式选择纯色键控或通用智能分割。

纯色模式支持颜色输入和吸管取色,并以本地算法处理任意键色。

通用模式逐帧使用 BgFilter complex 分割,禁止携带键色。

入队与 durable worker 统一校验模式参数并持久化权威处理元数据。

补充双色键控、模式冲突、双路径路由和前端交互回归。

同步更新 Spine 技术方案与团队决策记录。
This commit is contained in:
2026-08-17 15:27:13 +08:00
parent ae5c2d8821
commit 3d145379f2
13 changed files with 665 additions and 33 deletions
@@ -14185,3 +14185,10 @@
- 背景:视频模式的 `appearanceReferenceSrcs` 原先会在 Provider 调用前逐项下载并完整解码,但该实际执行路径没有复用通用视频参考的 9 张数量上限,也没有单图、累计字节、解码边长和像素预算,可能让第 10 张或压缩炸弹图片持续占用 durable worker 资源。
- 决策:角色外观图最多 9 张,单图最大 30MB、合计最大 64MB,编码边长最大 8192、单图总像素最大 33554432。前端上传追加与草稿恢复收口到 9 张;HTTP 入队和 worker 共用请求归一化数量门禁;worker 在 Provider 调用前按 OSS HEAD、流式下载字节上限、解码器资源限制及显式像素计算失败关闭。既有 owner、稳定 objectKey、MIME 和来源资源校验继续保留。
- 验证:覆盖 9/10 张边界、30MB 单图字节边界、8192 边长及总像素边界,并运行角色动作 Rust 定向测试、相关前端 Vitest、类型检查、编码与 diff 门禁。
## 2026-08-17 Spine 视频转换去背景改为显式双模式
- 背景:仅凭 `generationInputs.action = character-animation.convert` 无法证明源视频是绿幕;把任意转换结果固定按 `#00FF00` 键控会误处理普通背景或绿色主体。仓库已有 BgFilter `complex + birefnet` 通用分割服务,也已有可传 `screen_color` 的 flat 协议,但纯色场景不需要承担外部服务成本。
- 决策:只有视频直接转换序列继续显示“去背景”,点击后必须在独立弹窗显式选择 `solid-color``general`。纯色模式默认 `#00FF00`,允许颜色输入及浏览器吸管,后端使用参数化本地键色算法;通用模式逐帧调用 BgFilter complex,不携带键色。HTTP 入队和 durable worker 共用白名单校验,后端在结果 `generationInputs` 中权威记录模式、颜色或 Provider/model,不能再把“视频转换”本身当作绿幕证明。两种模式仍生成新序列资源、整批失败关闭并保留源序列。
- 费用边界:本次沿用现有手动 BgFilter 的 0 泥点内部契约;供应商成本不等于已确定的用户泥点售价,在没有正式定价决策时不自行新增价格。若后续收费,必须接入统一后端定价、入队冻结价格和 worker 扣费退款链路。
- 验证:覆盖缺失/非法纯色、通用模式禁止颜色、任意键色透传、绿色主体在非绿色键色下保留、双模式 worker 路由、前端模式选择及吸管回填,并运行角色动作 Rust 定向测试、前端 Vitest、类型检查、编码和 diff 门禁。
@@ -603,14 +603,16 @@ flowchart TD
#### 去背景
AI 生成链默认逐帧去背景,视频直接转换固定保留源背景。只有 `character-animation.convert` 的视频直接转换结果提供 `去背景`;AI 生成的序列帧已自动完成去背景,不展示也不接受重复处理。`character-animation` 浮动工具栏在适用时提供 `去背景`,与 `改造 / 拆帧 / 下载` 并列;点击后必须走现有 durable 派生任务,不得把序列第一帧当普通图片处理。派生任务保持以下边界:
AI 生成链默认逐帧去背景,视频直接转换固定保留源背景。只有 `character-animation.convert` 的视频直接转换结果提供 `去背景`;AI 生成的序列帧已自动完成去背景,不展示也不接受重复处理。`character-animation` 浮动工具栏在适用时提供 `去背景`,与 `改造 / 拆帧 / 下载` 并列;点击后弹出独立选择框,用户必须显式选择处理方式,再进入现有 durable 派生任务,不得把序列第一帧当普通图片处理。派生任务保持以下边界:
- `solid-color` 为本地纯色键控,默认 `#00FF00`,允许颜色输入和浏览器吸管选择任意 `#RRGGBB`;该模式不调用 BgFilter、阿里云或其它外部模型。
- `general` 为通用智能分割,不携带 `screenColor`,逐帧调用 BgFilter `complex + birefnet`;普通背景不再被隐式当作绿幕处理。当前内部接口沿用现有手动 BgFilter 的 0 泥点契约,不在缺少正式定价决策时自行发明用户收费金额;外部供应商成本与后续用户定价另行配置。
- 前端只负责显式选择;HTTP 入队与 durable worker 共用白名单校验:纯色模式必须携带合法颜色,通用模式禁止携带颜色。worker 只读取已持久化任务参数,最终资源的 `generationInputs` 由后端写入模式、键色或 Provider/model,不信任客户端自报配方。
- 原始不透明序列与透明序列是两个正式 resource;
- 去背景全帧成功后一次性发布新的 `character-animation` / `image-sequence` 资源、素材和画布图层,保留原始序列图层不被替换;
- 任一帧失败不产生残缺结果;
- v1 去背景仅支持编辑器权威 `character-animation.convert` 视频直接转换结果;AI 生成的序列帧、已去背景结果、缺失或非法生成配方均由后端拒绝,前端不展示该入口;
- 当前费用固定为 0 泥点,失败不产生不完整正式结果;请求先进入现有 `external_generation_job` 队列,不能由 HTTP 请求同步执行。
- 队列 worker 保持一个父 job,在 job 内按帧并行执行下载、纯本地绿幕扣除、最终 PNG 上传和帧对象准备;所有已发出的帧必须 drain 完成后再按帧号排序,一帧失败即清理未提交对象并整批失败,不新增逐帧子任务表或独立计费。
- 去背景仅支持编辑器权威 `character-animation.convert` 视频直接转换结果;AI 生成的序列帧、已去背景结果、缺失或非法生成配方均由后端拒绝,前端不展示该入口;
- 请求先进入现有 `external_generation_job` 队列,不能由 HTTP 请求同步执行。队列 worker 保持一个父 job,在 job 内按帧并行执行处理、最终 PNG 上传和帧对象准备;所有已发出的帧必须 drain 完成后再按帧号排序,一帧失败即清理未提交对象并整批失败,不新增逐帧子任务表。
- 帧对象路径绑定本次 job 的 `operationId`,同一 job 重放复用路径,不同 job 即使请求 fingerprint 相同也不得复用旧 object location,避免新 `asset_object` 与历史结果发生幂等冲突。
#### 拆帧