Files
gplan-2/tools/gen_palette_baseline.py
T
DKChan 9c36c7a237 工程(工程清理批·用户令): 六件直改合批——①palette_check基线建档+双门②机检化: golden/palette_baseline两PNG(token92色∪素材快照1274色=并集1346色)+gen_palette_baseline.py建档刷新件+闸脚本05b色板闸(code域,quick/影响面SKIP)+头注基线纪律, 门①语义检查与48计数上限不承载(口径归art-bible owner,呈报); ②extract_checks补check_quiet静默通道: CALL_RE/DEF_RE扩双通道+collect_call按匹配长偏移+quiet列记channel:check_quiet, 自证三重(双计等式2155==2155/新旧对拍1719→2133=+414入账/往返--diff PASS零差异), test-conventions§5.2局限备案句随批换代; ③样张S1b四色墨×PANEL_DATA垫牌≥4.5:1色值对表断言(读数4.97–5.62与审计复算逐位一致, 样张31/31全绿; V10基线对拍图artwork环境件--save-baseline重建); ④main.gd死preload清理10条(登记8条复核多出2条, 7具名消费面已迁main_ui_build拆件自持, 逐条grep复核零代码使用), presentation 17套件全绿+冒烟15项0失败兜底; ⑤注释换代: ui_kit TEX_HERO_PORTRAIT「48px档」→原稿分辨率+显示档读PORTRAIT_DISPLAY_H, path_check头注删日期批注记; ⑥CAMP_HEADER_BAND退役评估: 4处消费面核过(关卡屏2/商店1/KeystoneBadge工厂1), 退役删除不成立, 处置=改名中性化归ui_kit令牌批顺带(零值变化); ⑦run_all_gates 02传参核查=d32ff342已完成漏删零改动; 待办清单7条目整条删除(状态机出口), pipeline_gate PASS(33条目/49总表行); 产出物=reports/工程改动报告-工程清理批-2026-11-02.md
2026-11-02 06:29:27 +08:00

106 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""色板基线生成器——palette_check 双门②基线的建档与刷新件。
产出两张 1×N 条带 PNG 落 game/tests/golden/palette_baseline/(图像白名单在册目录):
ui_tokens.png = ui_kit.gd 全量 Color8 常量唯一色值(token 板现役值快照)
art_snapshot.png = 现役素材(game/assets/art 递归)全量唯一色快照(像素板+各屏环境子板)
palette_check --baseline 取目录下全部 PNG 的唯一色并集为「既有色板」;基线缺一张
即漏判——基线刷新必须重生成全套。维护纪律:素材批收尾跑一次本器刷新并随批提交
(新色过门②后须入基线,否则下批扫描把已过门的新色再报新增)。
用法:
python tools/gen_palette_baseline.py [--repo <仓库根>]
退出码: 0 成功 / 2 前置缺位(ui_kit.gd 或素材目录缺 / 素材零 PNG)
"""
import argparse
import os
import re
import sys
from PIL import Image
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from palette_check import palette_of # 排除全透明的唯一色提取——与检查器同口径
def strip_comments(text):
"""剔 GDScript 行注释与字符串字面量,防注释里举的色值被误收进 token 快照。"""
out = []
for line in text.split("\n"):
i = line.find("#")
if i != -1:
line = line[:i]
out.append(line)
return "\n".join(out)
def token_cols(ui_kit_path):
"""ui_kit.gd 全量 Color8 唯一色值集合。"""
text = strip_comments(open(ui_kit_path, encoding="utf-8").read())
vals = re.findall(r"Color8\((\d+),\s*(\d+),\s*(\d+)\)", text)
return sorted(set((int(r), int(g), int(b)) for r, g, b in vals))
def scan_dirs(roots):
"""递归扫 PNG,唯一色并集(含像素位置首见序不保——并集无序)。"""
cols = set()
count = 0
for root in roots:
for dirpath, _, names in os.walk(root):
for fn in sorted(names):
if fn.lower().endswith(".png"):
c, _n = palette_of(os.path.join(dirpath, fn))
cols |= c
count += 1
return cols, count
def write_strip(cols, out_path):
"""1×N 条带 PNG(一色一像素列)。"""
cols = sorted(cols)
im = Image.new("RGB", (len(cols), 1))
for i, c in enumerate(cols):
im.putpixel((i, 0), c)
im.save(out_path)
return len(cols)
def main():
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
ap = argparse.ArgumentParser(description="色板基线生成器(token∪素材快照)")
ap.add_argument("--repo", default=".", help="仓库根(含 game/ 与 tools/)")
args = ap.parse_args()
ui_kit = os.path.join(args.repo, "game", "presentation", "views", "ui_kit.gd")
artdir = os.path.join(args.repo, "game", "assets", "art")
outdir = os.path.join(args.repo, "game", "tests", "golden", "palette_baseline")
if not os.path.isfile(ui_kit):
print("[gen_palette_baseline] FAIL:ui_kit.gd 缺:%s" % ui_kit)
return 2
if not os.path.isdir(artdir):
print("[gen_palette_baseline] FAIL:素材目录缺:%s" % artdir)
return 2
os.makedirs(outdir, exist_ok=True)
tcols = token_cols(ui_kit)
n_t = write_strip(tcols, os.path.join(outdir, "ui_tokens.png"))
acols, npng = scan_dirs([artdir])
if npng == 0:
print("[gen_palette_baseline] FAIL:素材目录零 PNG(素材未同步)——拒绝生成空快照")
return 2
n_a = write_strip(acols, os.path.join(outdir, "art_snapshot.png"))
union = set(tcols) | set(acols)
print("[gen_palette_baseline] 已生成:ui_tokens.png %d 色 / art_snapshot.png %d 色"
"(素材 %d 张 PNG);基线并集 %d 色 → %s"
% (n_t, n_a, npng, len(union), outdir))
return 0
if __name__ == "__main__":
sys.exit(main())