Files
gplan-2/tools/golden_compare.py
T
DKChan 126e583fed 工程(基线合一批·golden单基线跨平台+补锚14张+审核关卡立规): 分平台基线机制拆除(2026-11-08用户裁:跨平台渲染必须一致,禁加基线消化差异)——windows 6件基线提升到golden/根,删windows/mac两平台目录与根目录遗留(level_map.png+边车,零引用核实); 闸件去平台化(render_gate.sh GOLDEN直拼/golden_compare.py删_PLAT与plat_missing/golden_baseline_refresh.sh落点改根+--screens换代入口); 拆自愈采集(ci.yml步+tools/ci/golden_selfheal.sh——CI自动落基线=既当裁判又当选手,测量数据已采完退役); 补锚14张(用户裁:发现少了就补,备案清零)——shot_probe扩九态(营地五窗真点热点开窗/图例真点钮/战末结算与三选一直调喂真实形态文案/调试浮窗直调)+battle段呼吸相位冻结(motion_scale0.5+1.2s动画完结锚定,board_shot同款)+热点键→基线语义名映射(dummy→tree/board→codex); 渲染闸屏态浮层golden段(golden_compare 14面)+shot_checker 16屏清单; 基线审核关卡立规(test-conventions §8.2:逐张审核确认后才入库生效+审核记录落档+非卡片批基线操作同关卡;process-conventions五·实现行:未审核的基线禁合回;req-card/iter技能特殊标注——豁免面直改); 实测依据: mac真渲染vs windows基线四指标(棋盘0.025~0.033%/menu 0.674% changed,RGB零色偏,块平均≈0)全在容差带内——数据归档reports/基线合一批-反哺点-2026-11-08.md; 读数: shot_probe直跑16图问题=0+渲染闸直跑exit=0(20面全PASS,新候选changed=0.00%)+bash -n×3+py_compile+文档域闸绿; 基线审核记录: 20张全部DKChan 2026-11-08确认(README审核记录节)
2026-11-08 23:19:47 +08:00

74 lines
3.1 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
r"""golden_compare.py — C 档黄金图对比(呈现层测试分级·渲染闸周期件)。
用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...]
默认屏清单 = shot_menu.png shot_camp.png shot_level.png shot_battle.png。
判据(容差口径,v1 冻结):
① 四屏存在且尺寸一致(与黄金图逐屏比对);
② 逐像素灰度差 >16 的像素占比 ≤2%(抗锯齿/微噪声容差带——结构级变化必超带);
③ changed 占比 >2% 即 FAIL(视觉回归信号——逐屏列差异热区提示)。
基准冻结于 v3.5 视觉落码+营地终稿+分辨率案甲后;资产升档换代时显式重制基准。
退出码: 0 = 全过 / 1 = 有失败。
"""
import sys
from pathlib import Path
from PIL import Image, ImageChops
TOLERANCE = 16 # 灰度差容差(单通道)
FAIL_RATIO = 0.02 # changed 占比失败线
# 单基线跨平台(2026-11-08 用户裁:跨平台渲染必须一致)——全平台对拍同一份基线,
# 跨平台字形锯齿噪声由容差带吸收(实测:棋盘 ≤0.033% / menu ≤0.68% changed,预算 ≤2%);
# 超容差即红(视觉回归或跨平台失配,均须人工排查,禁加基线消化)。
def compare(base: Path, curr: Path, name: str, failures: list) -> None:
pb, pc = base / name, curr / name
if not pb.exists():
failures.append("%s: 黄金图缺失(基准未建)" % name)
return
if not pc.exists():
failures.append("%s: 新截图缺失" % name)
return
a = Image.open(pb).convert("L")
b = Image.open(pc).convert("L")
if a.size != b.size:
failures.append("%s: 尺寸 %s != 基准 %s" % (name, b.size, a.size))
return
diff = ImageChops.difference(a, b)
hist = diff.histogram()
total = a.size[0] * a.size[1]
changed = sum(hist[TOLERANCE + 1:]) / total
print("[golden] %s — changed=%.2f%%(容差 ≤%.0f 差/≤%.0f%%)%s" % (
name, changed * 100, TOLERANCE, FAIL_RATIO * 100, "OK" if changed <= FAIL_RATIO else "FAIL"))
if changed > FAIL_RATIO:
failures.append("%s: changed %.2f%% > %.0f%%(视觉回归——核对热区后重制或修复)" % (name, changed * 100, FAIL_RATIO * 100))
def main() -> int:
if len(sys.argv) < 3:
print("用法: python tools/golden_compare.py <黄金图目录> <新截图目录> [屏清单...]")
return 1
base, curr = Path(sys.argv[1]), Path(sys.argv[2])
if not base.is_dir():
print("[golden] FAIL — 基线目录未建:%s" % base)
print(" 处置:跑 tools/golden_baseline_refresh.sh 重制基线并提交(基线换代权限 Q6)")
return 1
shots = sys.argv[3:] or ["shot_menu.png", "shot_camp.png", "shot_level.png", "shot_battle.png"]
failures = []
for name in shots:
compare(base, curr, name, failures)
if failures:
print("[golden] FAIL——")
for f in failures:
print(" - %s" % f)
return 1
print("[golden] PASS(%d 屏黄金图对比全过)" % len(shots))
return 0
if __name__ == "__main__":
sys.exit(main())