65 lines
2.7 KiB
Python
65 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
||
r"""golden_board_crop.py — 棋盘 golden 前置裁剪(迭代 19 卡① T2 2026-10-08)。
|
||
|
||
board_shot_probe 截整屏视口(get_viewport().get_texture()),golden 逐像素对比前须裁出棋盘区。
|
||
本工具按 board_meta.json 取样坐标(board_shot_probe 输出的棋盘视图实测全局矩形)裁剪,
|
||
**禁硬编码像素**(迭代 15③ 挂账口径——布局改动只须重跑探针刷新 meta,裁剪代码零改动)。
|
||
|
||
用法: python tools/golden_board_crop.py <board_meta.json 路径> <截图目录> <输出目录>
|
||
输出: <输出目录>/board_<tag>.png(tag=meta 键,如 L1_dungeon)。
|
||
|
||
容错:矩形越界按图像边界收拢;meta 键缺失/矩形退化(宽高≤0)= 报错退出 1(取证缺失不静默)。
|
||
退出码: 0 = 全部裁出 / 1 = 有失败。
|
||
"""
|
||
import json
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
from PIL import Image
|
||
|
||
|
||
def main() -> int:
|
||
if len(sys.argv) != 4:
|
||
print("用法: python tools/golden_board_crop.py <board_meta.json> <截图目录> <输出目录>")
|
||
return 1
|
||
meta_p, src_d, dst_d = Path(sys.argv[1]), Path(sys.argv[2]), Path(sys.argv[3])
|
||
if not meta_p.exists():
|
||
print("[golden_crop] FAIL — board_meta.json 缺失: %s" % meta_p)
|
||
return 1
|
||
meta = json.loads(meta_p.read_text(encoding="utf-8"))
|
||
if not meta:
|
||
print("[golden_crop] FAIL — board_meta.json 空表(取样坐标零在案)")
|
||
return 1
|
||
dst_d.mkdir(parents=True, exist_ok=True)
|
||
failures = []
|
||
for tag, r in meta.items():
|
||
src = src_d / ("board_%s.png" % tag)
|
||
if not src.exists():
|
||
failures.append("%s: 截图缺失 %s" % (tag, src))
|
||
continue
|
||
img = Image.open(src).convert("RGB")
|
||
try:
|
||
x, y, w, h = int(r["x"]), int(r["y"]), int(r["w"]), int(r["h"])
|
||
except (KeyError, TypeError, ValueError):
|
||
failures.append("%s: meta 矩形字段缺失/非法 %s" % (tag, r))
|
||
continue
|
||
# 越界收拢到图像边界(全局 rect 可能触视口边)
|
||
box = (max(0, x), max(0, y), min(img.size[0], x + w), min(img.size[1], y + h))
|
||
if box[2] - box[0] <= 0 or box[3] - box[1] <= 0:
|
||
failures.append("%s: 矩形退化 %s(img %s)" % (tag, box, img.size))
|
||
continue
|
||
img.crop(box).save(dst_d / ("board_%s.png" % tag))
|
||
print("[golden_crop] %s — %s -> %s(%dx%d)" % (tag, box, dst_d / ("board_%s.png" % tag),
|
||
box[2] - box[0], box[3] - box[1]))
|
||
if failures:
|
||
print("[golden_crop] FAIL——")
|
||
for f in failures:
|
||
print(" - %s" % f)
|
||
return 1
|
||
print("[golden_crop] PASS(%d 张棋盘区裁剪全出)" % len(meta))
|
||
return 0
|
||
|
||
|
||
if __name__ == "__main__":
|
||
sys.exit(main())
|