Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import json | |
| from pathlib import Path | |
| from PIL import Image, ImageDraw, ImageFont | |
| def _load_cfg(path: Path) -> dict: | |
| return json.loads(path.read_text(encoding="utf-8")) | |
| def _is_zero(pt) -> bool: | |
| try: | |
| return int(pt[0]) == 0 and int(pt[1]) == 0 | |
| except Exception: | |
| return True | |
| def main() -> int: | |
| root = Path(__file__).resolve().parents[1] | |
| img_path = root / "outputs" / "bluestacks" / "validate_base.png" | |
| cfg_path = root / "config" / "bluestacks_gameplay.local.json" | |
| out_path = root / "outputs" / "bluestacks" / "validate_overlay.png" | |
| if not img_path.exists(): | |
| raise SystemExit(f"missing screenshot: {img_path}") | |
| if not cfg_path.exists(): | |
| raise SystemExit(f"missing calibration: {cfg_path}") | |
| cfg = _load_cfg(cfg_path) | |
| img = Image.open(img_path).convert("RGBA") | |
| draw = ImageDraw.Draw(img) | |
| try: | |
| font = ImageFont.truetype("Arial.ttf", 18) | |
| except Exception: | |
| font = ImageFont.load_default() | |
| points: list[tuple[str, tuple[int, int], str]] = [] | |
| # Card slots | |
| for k in ("1", "2", "3", "4"): | |
| pt = cfg.get("card_slots", {}).get(k, [0, 0]) | |
| points.append((f"S{k}", (int(pt[0]), int(pt[1])), "yellow")) | |
| # Key grid cells | |
| for cell in ("A1", "A8", "H1", "H8", "E2", "E7", "D2", "D7"): | |
| pt = cfg.get("grid", {}).get(cell, [0, 0]) | |
| points.append((cell, (int(pt[0]), int(pt[1])), "cyan")) | |
| # Draw points | |
| for label, (x, y), color in points: | |
| r = 10 | |
| fill = (255, 0, 0, 180) if (x == 0 and y == 0) else (0, 0, 0, 0) | |
| outline = (255, 64, 64, 255) if (x == 0 and y == 0) else (0, 255, 255, 255) if color == "cyan" else (255, 255, 0, 255) | |
| draw.ellipse([x - r, y - r, x + r, y + r], fill=fill, outline=outline, width=3) | |
| draw.rectangle([x + 12, y - 12, x + 12 + 46, y + 12], fill=(0, 0, 0, 160)) | |
| draw.text((x + 16, y - 10), label, fill=(255, 255, 255, 255), font=font) | |
| # Header | |
| header = f"Calibration overlay | cfg={cfg_path.name} | red = (0,0) invalid" | |
| draw.rectangle([0, 0, img.size[0], 34], fill=(0, 0, 0, 200)) | |
| draw.text((10, 8), header, fill=(255, 255, 255, 255), font=font) | |
| img.save(out_path) | |
| print(out_path) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |