mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 09:17:31 +00:00
chore(mascot): 立绘 v2 —— 真 alpha 素材 + 头部裁切头像 + 素材判据
老大给的 4 张新立绘里有 3 张是「棋盘格假透明」JPEG(像素是灰白格子,
不是 alpha)。直接进仓库会在深色面板上露出格子,所以先抠成真 alpha 再落盘。
## 为什么主图与头像要分两个文件
现役 mascot.webp 唯一的消费点是**聊天消息的 30px 圆形头像**
(dashboard.js 4 处 aiAvatar + GUI app.js 2 处),概览页并没有放立绘。
主图是坐姿全身,按现有 CSS(object-fit:cover + scale(1.5))裁成圆后
只剩裙子、看不到脸 —— 只换图不做头像版,等于把头像换成一张看不懂的图。
- assets/branding/mascot-xiaozhai.webp 1024² 主立绘(官方展示)
- assets/branding/mascot-xiaozhai-avatar.webp 512² 头部方裁(运行期源)
- internal/plugins/webui/mascot.webp 256² 头像版(原 133KB→24KB)
- cmd/gui/renderer/mascot.webp 128² 头像版(原 133KB→9KB)
参考稿另存三张(不参与运行):sheet(设定总图)/ portrait(半身)/
turnaround(三视图)。
## 抠图怎么做的(可复现,不是手搓)
背景是 20.45px 周期的棋盘格(237/254 两色)。判据取「中性灰 且 灰度≥228」
的像素做候选,再从图像边界做连通域传播 —— 这样白裙子/白围裙因为不中性
(带蓝调)不会被误判,避免了当年 site/README 记录的 flood-fill 渗色问题。
边界再内缩 1px 抹白边,0.7px 高斯羽化去锯齿。抠完透明占比 55.8%,
深/浅两种背景上目检均无残留格子与白边。
## CSS:scale(1.5) → 1.25
原来的 1.5 是为「全身图裁圆」补的放大。换成头部方裁后,1.5 会切掉两侧
发绳与呆毛 —— 按真实 30px 渲染放大对照看过 1.0/1.15/1.25/1.4 四档。
## 新增判据(含反向验证)
internal/plugins/webui/mascot_asset_test.go 直接读 WebP 容器头,
断言 VP8X 的 Alpha 标志位与 ALPH chunk **同时存在**,外加正方形/≥128px/
≤128KB。理由:这类退化在肉眼 review 里抓不住(缩到 30px 就是一团浅色),
而用户每天都在看;且 site/README.md 记着当年正因为「白底图没法抠」
干脆不放立绘,这个坑值得一个自动化判据。
反向验证(已实跑,非声称):把素材换成 HEAD 旧图,判据报红并准确指出
「Alpha 标志位未置位 / 缺 ALPH chunk / 体积超限」;换回新图转绿。
另有一条独立用例构造「带 VP8X 但不置 Alpha 位」的最小容器,
确认解析器不会对退化素材误判为绿。
## 顺带修的两处
1. assets/docs/{zh,en}/PLUGIN_DEV.md 的 mascot 引用路径是坏的:
`../../assets/branding/...` 从 assets/docs/zh/ 出发解析成
`assets/assets/branding/...`,文件不存在(旧版一直是坏的)。
已改为 `../../branding/...` 并逐条验证路径可解析。
同时指向新的头像版(那处是 20px 圆形内联小图标)。
2. gzip.go / gzip_test.go 注释里的「mascot.webp(133KB)」改为不带死数字
的说法 —— 体积会随素材变,注释写死数字只会变成误导。
## 验证
go build ./... → 0
go vet ./internal/plugins/webui/ ./cmd/gui/ → 干净
gofmt -l → 空
go test ./internal/plugins/webui/ -count=1 → ok(15.1s,含新增 2 个用例)
## 没做的事
- 没碰 main、没开 PR、没部署、没重启服务。
- **概览页仍未放立绘**。site/README 里「素材不可用」这条已不成立(素材有
alpha 了),但版面是否该放图属于设计取舍,不在本次范围 —— 文档已相应改写,
不再用「素材不行」当理由。
- 抠图对发丝边缘是「够用」不是「完美」:0.7px 羽化在 1024 下看不出来,
但若将来要印物料级大图,需要重出带原生 alpha 的源图。
This commit is contained in:
BIN
assets/branding/mascot-xiaozhai-avatar.webp
Normal file
BIN
assets/branding/mascot-xiaozhai-avatar.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
@ -258,6 +258,33 @@ dynamic flowing hair and fabric,
|
||||
|
||||
---
|
||||
|
||||
## 素材清单(assets/branding/)
|
||||
|
||||
| 文件 | 尺寸 | 用途 | alpha |
|
||||
|------|------|------|-------|
|
||||
| `mascot-xiaozhai.webp` | 1024×1024 | **主立绘**(坐姿全身,官方展示用) | ✅ 真 alpha |
|
||||
| `mascot-xiaozhai-avatar.webp` | 512×512 | **头像**(头部方裁,脸居中) | ✅ 真 alpha |
|
||||
| `mascot-xiaozhai-sheet.webp` | 1024×1536 | 设定总图(配色/通道线/道具标注) | — |
|
||||
| `mascot-xiaozhai-portrait.webp` | 1024×1536 | 半身胸像(三只工具特写清晰) | — |
|
||||
| `mascot-xiaozhai-turnaround.webp` | 1200×800 | 三视图(正/侧/背) | — |
|
||||
|
||||
**为什么主图与头像分两个文件**:主图是全身坐姿,直接塞进 30px 圆形头像里
|
||||
(`object-fit: cover` 会把画面中心裁成正方形)只会剩裙子、看不到脸。
|
||||
头像版是**头部方裁**,圆形裁切后脸正好居中。
|
||||
|
||||
运行期副本(由上面两张生成,勿单独手改):
|
||||
|
||||
| 路径 | 尺寸 | 说明 |
|
||||
|------|------|------|
|
||||
| `internal/plugins/webui/mascot.webp` | 256×256 | WebUI 对外 `/mascot.webp`(嵌入二进制) |
|
||||
| `cmd/gui/renderer/mascot.webp` | 128×128 | GUI 聊天头像 + agent 光标(以 data URL 注入) |
|
||||
|
||||
这两个文件的 alpha 由 `internal/plugins/webui/mascot_asset_test.go` 判定:
|
||||
直接读 WebP 容器头,要求 VP8X Alpha 标志位与 `ALPH` chunk 同时存在。
|
||||
换素材时若塞进一张「白底图」或「棋盘格图」,判据会红。
|
||||
|
||||
---
|
||||
|
||||
## 设计注意事项
|
||||
|
||||
1. **三色丝带是核心识别元素**,在任何立绘/插画中必须保留
|
||||
|
||||
BIN
assets/branding/mascot-xiaozhai-portrait.webp
Normal file
BIN
assets/branding/mascot-xiaozhai-portrait.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
BIN
assets/branding/mascot-xiaozhai-sheet.webp
Normal file
BIN
assets/branding/mascot-xiaozhai-sheet.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 211 KiB |
BIN
assets/branding/mascot-xiaozhai-turnaround.webp
Normal file
BIN
assets/branding/mascot-xiaozhai-turnaround.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 133 KiB |
@ -2,7 +2,7 @@
|
||||
|
||||
# HomeAgent Plugin Development Guide
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## Overview
|
||||
|
||||
@ -35,7 +35,7 @@ type Plugin interface {
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 1. Quick Start: Using the hmapdev Toolchain
|
||||
|
||||
@ -243,7 +243,7 @@ curl -X POST http://127.0.0.1:8080/api/v1/plugins \
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 2. Go Plugin Development in Detail
|
||||
|
||||
@ -538,7 +538,7 @@ outputCh := s.OutputChan()
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 3. Lua Plugin Development in Detail
|
||||
|
||||
@ -680,7 +680,7 @@ Each `attachments` item: `{ digest=, mime=, name=, data=<base64> }`; with `data`
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 4. Built-in Plugins
|
||||
|
||||
@ -745,7 +745,7 @@ import (
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 5. Best Practices
|
||||
|
||||
@ -759,7 +759,7 @@ import (
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 6. Plugin Management
|
||||
|
||||
@ -801,7 +801,7 @@ Internal: records are stored in SQLite `disabled_plugins` table (`name`, `disabl
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 7. Example Plugin Reference
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
# HomeAgent 插件开发指南
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 概述
|
||||
|
||||
@ -36,7 +36,7 @@ type Plugin interface {
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 一、快速开始:使用 hmapdev 工具链
|
||||
|
||||
@ -241,7 +241,7 @@ curl -X POST http://127.0.0.1:8080/api/v1/plugins \
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 二、Go 插件开发详解
|
||||
|
||||
@ -531,7 +531,7 @@ outputCh := s.OutputChan()
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 三、Lua 插件开发详解
|
||||
|
||||
@ -673,7 +673,7 @@ end)
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 四、内置插件
|
||||
|
||||
@ -738,7 +738,7 @@ import (
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 五、最佳实践
|
||||
|
||||
@ -752,7 +752,7 @@ import (
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 六、插件管理
|
||||
|
||||
@ -792,7 +792,7 @@ pmgr.ReloadPlugins() // 重载所有插件
|
||||
|
||||
---
|
||||
|
||||
<img src="../../assets/branding/mascot-xiaozhai.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
<img src="../../branding/mascot-xiaozhai-avatar.webp" width="20" style="border-radius:50%;vertical-align:middle"> :
|
||||
|
||||
## 七、示例插件参考
|
||||
|
||||
|
||||
Reference in New Issue
Block a user