feat(theme-builder): 图片处理——透明度 / 压白 / 去色 / 裁边 / 去白底

素材卡片左上角 fx 按钮进处理面板,非破坏:
- orig 存上传时的原始字节(不重编码),fx 只存参数,每次从 orig 重算。
  「压白 16% → 20%」不会叠加两次压缩;打开看一眼就关一个像素都不动
  (参数没变直接跳过,有损编码反复走会累积模糊)。
- 预览按 420px 宽算(滑杆要跟手),完成时用全分辨率重算;加了序号丢弃过期结果,
  否则快速拖动时旧渲染会覆盖新的。

功能:
- 不透明度 0~100%(CSS 背景图没法单独设 opacity,只能烘焙)
- 压白 v×(1-k)+255×k,与主题里场景的雾度同一公式
- 去色、裁掉透明边
- 去白底:四边漫水 + 封闭白孔检测 + 可选 1px 收边

去白底两个坑(都写进注释了):
- 手内侧 / 两腿之间是闭合白区,四边漫水进不去,得按连通域单独掏(面积≥24)
- 容差默认 16 而不是 22:背景 253、白袜子 237 只差 16,
  容差 30 会把袜子吃穿成一个透明洞

验证(都是跑出来的,不是看缩略图):
- ?dump=fx 13 项算法断言全过:封闭孔开/关、容差 16 保袜子/30 吃穿、
  收边后轮廓 1px、alpha 50%→128、压白 20% 时 237→241、去色后 R=G=B、裁边 80×40
- ?dump=fxpipe 链路:弹窗开关、预览 300×960、参数重开后仍在、
  改参后 dataURL 变、无改动时 dataURL 一个字节不变
- ?dump=fxkey 端到端:白底立绘去白底后透明占比 46.3%,
  与手写 floodfill 抠的 46.6% 差 0.3%
- 生成 CSS 仍通过 TestThemeCSSComplete + TestDecoSlotCount

顺带:工程文件升到 v3(存 orig + fx,未处理时不重复存 dataURL),
读 v2 旧工程时把 dataURL 当 orig 用。新增 ?loadurl= 把项目里的图直接当素材载入。
This commit is contained in:
tamakyi
2026-10-20 14:52:36 +08:00
parent bf1c994c8f
commit c3d34b53d2
2 changed files with 680 additions and 21 deletions
+31 -2
View File
@@ -70,7 +70,29 @@ http://127.0.0.1:8777/dev/theme-builder/
(深色块特异性更高,本来就压住它)。
**图片池** —— 上传任意张,浏览器本地转 WebP,画布尺寸 = 原图尺寸(不缩放、不留透明边)。
导出时只打包实际用到的图。
导出时只打包实际用到的图。每张图左上角有 `fx` 按钮,进处理面板(处理过的会高亮)。
### 图片处理
| 功能 | 说明 |
| --- | --- |
| 不透明度 | 0~100%。CSS 背景图没法单独设 `opacity`,只能烘焙进像素 |
| 压白 / 雾度 | `v×(1-k)+255×k`。场景压白 38% 时人物常用 12~26%,否则是全页对比度最高的一块 |
| 去色 | 往灰度混。彩色素材压不住素场景时用 |
| 裁掉透明边 | 生成图四周留白多时裁掉,否则按高度定尺寸会让主体看着比实际小 |
| 去白底 | 四边漫水 + 封闭白孔检测,默认容差 16 |
| 边缘收 1px | 去白底后把残留的半透明白边收掉,代价是轮廓缩一圈 |
**非破坏**:原文件字节存在 `orig` 里,`fx` 只存参数,每次处理都从 `orig` 重算。
所以「压白 16% → 改成 20%」不会叠加两次压缩,反复调参也不会把边缘越磨越糊。
打开面板看一眼就关,一个像素都不会动(参数没变就跳过重编码)。
**去白底的两个关键点**(都是踩过的):
- **封闭白孔**:手内侧、两腿之间那种被轮廓包住的白色,四边漫水根本进不去,
必须单独按连通域掏(面积 ≥ 24 才掏,更小的多半是眼睛高光)。可以关掉。
- **容差别贪**:背景常见 253,白袜子 237,只差 16。容差 16 保得住袜子,30 就吃穿了。
实测白底立绘去白底后透明占比 46.3%,与手写 floodfill 抠出来的 46.6% 差 0.3%。
## 工程文件与草稿
@@ -104,7 +126,7 @@ INSTALL-<slug>.txt
## 它不做什么
- **不抠图**:图片必须本身是透明底,白底图导出的主题会带一块白。
- **不做复杂修图**:没有笔刷、蒙版、自由裁切、调色曲线 —— 这些该在专门的工具里做完再进来。
- **不做调色**:想统一「雾度」(人物压白 16%、场景 30~38%)得在生成端做,
见 `docs/theme-shiroko-assets-spec.md`。
- **不写配置**:`[theme] available` 只给要粘贴的那一行。
@@ -123,6 +145,13 @@ INSTALL-<slug>.txt
?dump=zip 把 zip 的 base64 写进 <pre id="dump">
?dump=validate 把 validate() 的结果写进 <pre id="dump">
?dump=install 把安装说明写进 <pre id="dump">
?dump=fx 跑处理算法自检(13 个断言,输出 JSON)
?dump=fxpipe 跑弹窗链路冒烟(打开→改参→预览→落盘→无改动不重编码)
?dump=fxkey 端到端去白底:载入白底图,统计透明像素比例
?loadurl=/static/images/x.webp&fx=x
直接把项目里的图当素材载入(不必先下载再上传),fx= 打开处理面板
?fxjson={"key":{"on":true}}
配合 loadurl 给初始处理参数
```
```bash