1. Wiki 形象圖「沒有同步」的真正原因
內容其實一直是一致的(md5 相同),但**頁面上看不到圖**:
Icon.md/Home.md 用了 HTML `<img src="icon.svg">`,而 Gitea **只改寫
Markdown 圖片語法**(`` → `/wiki/raw/icon.png`)。HTML 的 src
被瀏覽器解析成 `/wiki/icon.svg` → 303 轉址 → 破圖。
用公開的臨時庫實測四種寫法後確認,全部改成 Markdown 語法。
同時發現攤平規則過頭了:原本所有子目錄檔案都被壓成 `icon-portrait.svg`。
實測 `/wiki/raw/<資料夾>/<圖>` 是取得到的,所以**只有 .md 需要攤平**
(頁面必須在根層),圖片與附件保留資料夾結構。
2. icon/ 資料夾 + 高解析度
每次 `icon generate` 都會輸出並同步:
icon.svg / icon.png 512,Wiki 頁面與存取庫頭像
icon/portrait.svg 向量原稿
icon/portrait-512.png 高解析度
icon/portrait-1024.png 高解析度
柵格器加上每個圖形的 bounding box 裁剪,1024×1024(3× 超取樣)約 1.8 秒;
沒有裁剪的話要跑上億次點測試。
3. 更貼近原圖、更可愛
眼睛放大約 15%,虹膜改成四層(暗環→本色→下緣提亮→瞳孔)+雙高光,
眼線壓扁成細弧、外眼角加睫毛;頭髮加高光弧、髮絲與側髮反光;
臉型再圓一點、加下巴陰影與鼻子。
眉色改成隨髮色明暗調整:深髮往膚色提亮、淺髮比頭髮更深——否則不是和瀏海
連成黑帶,就是變成兩條灰槓。
selftest 168 項全綠(新增第 ⑱ 節:icon/ 多解析度、PNG 實際尺寸、只攤平 .md、
Wiki 頁面不得用 HTML img、bounding box 裁剪效能)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9.0 KiB
name, description
| name | description |
|---|---|
| persona-icon | 產生或更新人格的形象圖(icon.svg + icon.png,人物頭像、看得到臉):先上網找出該人格「最新一次登場」的官方視覺,裁出**大頭照當底稿**,親眼看過之後萃取髮色/瞳色/服裝色與髮型、眼型、表情、配件等特徵,再**由本工具依人格資料重新繪製**——絕不把找到的圖片直接當圖示。來源網址、底稿裁切框與重繪依據都會存進 config 備查,圖示同步到 Gitea Wiki(SVG + PNG)並設為存取庫頭像,且會回頭驗證同步結果。當使用者說要做人格頭像/形象圖/icon、要依角色最新造型更新圖示、說現在的圖示不像或看不到臉、或剛建立完人格要補圖示時觸發。不適用於:建立人格本身(persona-create/persona-anime,它們會叫用本技能的步驟)、同步到 Gitea(persona-sync)。 |
🎨 persona-icon — 依最新造型產生人格形象圖(有臉)
CLI:node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs"(帶 --session <PERSONA_SESSION>)
時機:人格建立且 IDENTITY/SOUL 補齊之後——形象綁在最終身分上。
目標:圖示要是人物形象圖,看得到臉;退而求其次才是抽象徽章。
鐵則:找到的圖片只能當底稿,不能當圖示。 網路上的角色圖是別人的美術作品。這裡的做法是「裁出大頭照 → 看清楚 → 依人格資料重新繪製」,產出的每一個像素都是本工具畫的。
為什麼要上網找圖
圖示要像這個人格,就得用他現在的樣子:動漫角色會換造型、換作品、換髮色。 所以流程是「查最新登場 → 看那張圖 → 取色 → 畫」,而不是憑印象填色。
步驟
1. 查出「最新一次登場」
用 WebSearch 找這個角色最近的官方動向(新作、新章節、新造型),至少確認:
- 最新的作品/章節名稱與年份
- 那個版本的造型敘述(髮色、瞳色、服裝主色)
搜尋語彙範例:<角色> <作品> 2026 新作 主視覺、<character> latest anime key visual outfit。
2. 取得一張真的參考圖
要直接的圖片網址(.png / .jpg),優先序:
-
官方新作的主視覺/key visual(新聞稿內的圖)
-
AniList 的官方角色圖——可直接查,不需登入:
curl -s -X POST -H "Content-Type: application/json" \ -d '{"query":"query{Media(id:<動畫 id>,type:ANIME){characters(perPage:25){nodes{name{full} image{large}}}}}"}' \ https://graphql.anilist.co -
其他公開的官方素材
下載下來:curl -sL -o /tmp/ref.png "<圖片網址>"
3. 親眼看過那張圖(不可省略)
用 Read 工具打開它。沒看過就不准填顏色——憑記憶填色等於編造。
從圖上讀出五個顏色(用取樣到的實際色,不是「大概是紅色」):
| 欄位 | 取哪裡 |
|---|---|
hair |
頭髮的主色(不是高光也不是陰影) |
eye |
瞳孔顏色 |
accent |
服裝最顯眼的主色 |
secondary |
服裝的第二色/配件色 |
light |
最亮的部位(白袖、皮膚亮面) |
4. 裁出大頭照當底稿
# 先看看圖裡有幾張臉——多角色的主視覺一定要先看
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" icon faces --session <PERSONA_SESSION> --photo "<圖片網址或路徑>"
# 裁出底稿(索引由左到右;也可以用 largest/leftmost/rightmost,或 --face x,y,w,h 自己框)
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" icon headshot --session <PERSONA_SESSION> --photo "<圖片網址或路徑>" --pick <索引>
底稿寫到 <人格>/.sync/headshot.png,不是圖示、不會同步、不會發佈。
多角色的圖務必自己看過再挑:icon faces 只給座標,哪張臉是本人要由你判斷。
裁完一定要用 Read 打開確認是本人——挑錯就是別人的臉。
工具不齊時 CLI 會印出安裝指令——不會靜默失敗。需要的工具:
| 工具 | 做什麼 | 怎麼裝(免 sudo) |
|---|---|---|
| Pillow | 解碼照片、裁切、縮放 | python3 -m venv ~/.cache/jsc-persona/venv && ~/.cache/jsc-persona/venv/bin/pip install pillow |
| OpenCV 4.x | 自動找臉的位置 | ~/.cache/jsc-persona/venv/bin/pip install "opencv-python-headless<5" |
| 動漫臉模型 | OpenCV 內建模型認不出動漫臉 | curl -sL -o ~/.cache/jsc-persona/lbpcascade_animeface.xml https://raw.githubusercontent.com/nagadomi/lbpcascade_animeface/master/lbpcascade_animeface.xml |
OpenCV 5.x 拿掉了
CascadeClassifier,一定要裝 4.x。 venv 放在~/.cache/jsc-persona/venv會被自動偵測到;也可以用PERSONA_PYTHON指定別的。
5. 看著底稿,把特徵讀出來
用 Read 打開 .sync/headshot.png,同時讀這個人格的 IDENTITY.md/SOUL.md/canon 記憶。
形象要同時對得起「他長什麼樣」與「他是誰」:
| 特徵 | 可選值 | 從哪裡判斷 |
|---|---|---|
hairstyle |
straight / twintails / ponytail / bob / braid | 底稿的髮型 |
length |
short / medium / long / very-long | 底稿的髮長 |
fringe |
blunt / parted / swept / curtain | 底稿的瀏海 |
eyes |
round / almond / sharp / droopy | 底稿的眼型 |
expression |
gentle / bright / calm / neutral | SOUL 的 Vibe + 底稿的神情 |
accessory |
none / ribbon / clip / flower / hairband | 底稿或最新造型的髮飾 |
side |
left / right | 髮飾在哪一側 |
collar |
round / v / high / sailor | 服裝領口 |
ahoge |
yes / no | 有沒有呆毛 |
6. 重新繪製
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" icon generate --session <PERSONA_SESSION> --force \
--palette "hair=#d9a45b,eye=#9e5b3e,accent=#c0392b,secondary=#e77a8e,light=#f2ebe3,skin=#f7ddc4" \
--features "hairstyle=straight,length=very-long,fringe=parted,eyes=almond,expression=calm,accessory=none,collar=v,ahoge=yes" \
--source-url "<底稿那張圖的網址>" \
--source-note "<作品(年份)+底稿是誰+重繪依據:髮型、眼型、神情、服裝>" \
--source-date <YYYY-MM-DD>
畫完一定要用 Read 打開產出的 icon.png 看一眼,不像就調特徵重畫(--force)。
--palette一定要配--source-url:配色是從哪張圖來的必須留得下來(CLI 會強制)。- 兩者都會寫進
state/config.json的icon欄位,之後icon show查得到。 - 產出的
icon.svg+icon.png會自動設成 Gitea 存取庫頭像、同步到 Wiki 區, 並在 Wiki 產生一頁 Icon(同時展示 SVG 與 PNG,附上來源網址與裁切框)。
找不到可靠的參考圖 → 不要硬掰,直接 icon generate 不帶 --palette,
用編號雜湊出的配色,並告訴使用者「沒找到最新造型的官方圖,先用預設配色」。
7. 回報
一句話說明:用了哪部作品哪一年的視覺、取到什麼配色、圖示放哪裡。 把來源網址附上,讓使用者可以自己核對。
三種樣式
| 樣式 | 什麼時候用 | 長什麼樣 |
|---|---|---|
portrait |
有底稿(有調色盤)→ 預設 | 依特徵重繪的人物頭像:髮型、瀏海、眼型、表情、髮飾、領口全部照特徵畫 |
badge |
完全沒有參考圖(原創人格) | 雙色漸層徽章 + 編號前兩個字母 |
- 兩種樣式都由 Node 自己柵格化,SVG 與 PNG 共用同一份圖形清單(橢圓/矩形/多邊形), 兩邊必然一致;PNG 是自寫的柵格器 + zlib 編碼,不依賴任何影像函式庫。
- 每次產生會輸出:
icon.svg/icon.png(512,頭像用)+icon/portrait.svg、icon/portrait-512.png、icon/portrait-1024.png(高解析度),全部同步到 Wiki。 - SVG 不會內嵌任何影像——沒有
<image>、沒有 base64、沒有外連。 badge樣式下若兩個顏色一深一淺(藍黑髮 + 淡粉洋裝),程式會把較亮的一端往較暗的壓, 確保字讀得到。
界線
- 找到的圖片只能當底稿:裁出來的大頭照留在
.sync/,不進圖示、不同步、不發佈。 圖示的每個像素都是本工具依特徵畫出來的。 - 底稿的來源網址會記在
config.json,方便日後核對,但不重製原圖。
Wiki 必須同步
icon generate 推完 Wiki 會自動回頭驗證,確認 icon.svg 與 icon.png 真的在 Wiki 上
而且與本機一致;不一致會直接報錯。也可以手動查:
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" sync verify --session <PERSONA_SESSION> --area wiki
邊界
- 只能對「本 session 已載入的人格」產生圖示。
- 已有圖示時要重畫必須加
--force。 - 不帶
--palette重畫會沿用 config 裡已存的配色(不會突然變回雜湊色)。 .sync/reference.*與.sync/headshot.png是底稿快取,可以安全刪除(不會同步出去)。- 所有面向使用者的輸出使用繁體中文(台灣用語)、UTF-8 無亂碼。