iter9-T7: 卡⑰a B 档视口截图基建试点(测试分级批同窗件)——shot_probe 窗口化四屏截图探针(菜单/营地/关卡/战斗,真实按钮信号路径驱动+存档/元进度/设置三面隔离档,双帧+frame_post_draw 同步抓视口纹理)+tools/shot_checker.py B 档断言骨架(尺寸 1280×800/灰度 std≥8/唯一色数≥64);实测四屏全过(std 18.6-64.9/色数 495-1745)落 artwork/qa-screens-20260930(不入 git);探针须窗口化运行(headless 无渲染面),T8 整屏样张闸四断言在此骨架上扩
This commit is contained in:
1 parent
1ecad0b580
commit
65e9016f7f
3 files changed
+165
No files matched your search
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
r"""shot_checker.py — 整屏截图 B 档断言骨架(迭代 9 卡⑰a 2026-09-30)。
|
||||
|
||||
用法: python tools/shot_checker.py <截图目录> [shot_menu.png shot_camp.png shot_level.png shot_battle.png]
|
||||
断言(v1 骨架——像素级可判层):
|
||||
① 四屏 PNG 存在且尺寸 = 1280×800(工程逻辑分辨率档);
|
||||
② 每屏灰度标准差 ≥ 8(非空白/非纯色——渲染真实发生的最低证据);
|
||||
③ 每屏唯一色数 ≥ 64(内容丰富度下限——占位纯色屏会落在个位数)。
|
||||
T8 整屏样张闸四断言(全局文字 ≥4.5:1/明度三档带/焦点预算/文字禁压纹理)在本骨架上扩。
|
||||
退出码: 0 = 全过 / 1 = 有失败。
|
||||
"""
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
|
||||
EXPECTED = (1280, 800)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if len(sys.argv) < 2:
|
||||
print("用法: python tools/shot_checker.py <截图目录> [屏清单...]")
|
||||
return 1
|
||||
d = Path(sys.argv[1])
|
||||
shots = sys.argv[2:] or ["shot_menu.png", "shot_camp.png", "shot_level.png", "shot_battle.png"]
|
||||
failures = []
|
||||
for name in shots:
|
||||
p = d / name
|
||||
if not p.exists():
|
||||
failures.append("%s: 文件缺失" % name)
|
||||
continue
|
||||
img = Image.open(p).convert("RGB")
|
||||
if img.size != EXPECTED:
|
||||
failures.append("%s: 尺寸 %s != %s" % (name, img.size, EXPECTED))
|
||||
continue
|
||||
gray = img.convert("L")
|
||||
hist = gray.histogram()
|
||||
total = sum(hist)
|
||||
mean = sum(i * c for i, c in enumerate(hist)) / total
|
||||
var = sum(c * (i - mean) ** 2 for i, c in enumerate(hist)) / total
|
||||
std = var ** 0.5
|
||||
colors = len({p2 for p2 in img.getdata()})
|
||||
if std < 8.0:
|
||||
failures.append("%s: 灰度 std %.1f < 8(疑似空白/纯色)" % (name, std))
|
||||
if colors < 64:
|
||||
failures.append("%s: 唯一色数 %d < 64(疑似占位屏)" % (name, colors))
|
||||
print("[shot_checker] %s — %s std=%.1f colors=%d %s" % (
|
||||
name, "x".join(map(str, img.size)), std, colors, "OK" if std >= 8 and colors >= 64 else "FAIL"))
|
||||
if failures:
|
||||
print("[shot_checker] FAIL——")
|
||||
for f in failures:
|
||||
print(" - %s" % f)
|
||||
return 1
|
||||
print("[shot_checker] PASS(%d 屏骨架断言全过)" % len(shots))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in new issue
Block a user