File size: 3,569 Bytes
dd96d2f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python3
"""
Upscale MAP.png en 4 passes (4 quadrants) via Vertex AI Imagen upscale.

La map étant trop lourde pour l'API en un seul appel (> 10 Mo), on :
  1. Découpe en 4 quadrants de 2048×2048
  2. Upscale chaque quadrant ×2  →  4096×4096 chacun
  3. Recolle en une image finale 8192×8192

Usage :
  cd backend && python -m scripts.upscale_map
  cd backend && python -m scripts.upscale_map --factor x2 --input static/MAP.png --output static/MAP.png
"""
from __future__ import annotations

import argparse
import io
import sys
from pathlib import Path

from PIL import Image

_backend = Path(__file__).resolve().parent.parent
if str(_backend) not in sys.path:
    sys.path.insert(0, str(_backend))

from scripts.upscale_cover import upscale_image


def upscale_map(
    input_path: Path,
    output_path: Path,
    factor: str = "x2",
) -> None:
    src = Image.open(input_path).convert("RGB")
    w, h = src.size
    print(f"Image source : {w}×{h}  ({input_path.stat().st_size / 1024 / 1024:.1f} Mo)")

    half_w, half_h = w // 2, h // 2
    quadrants = [
        (0,      0,      half_w, half_h),   # top-left
        (half_w, 0,      w,      half_h),   # top-right
        (0,      half_h, half_w, h     ),   # bottom-left
        (half_w, half_h, w,      h     ),   # bottom-right
    ]
    labels = ["top-left", "top-right", "bottom-left", "bottom-right"]

    upscaled_quadrants: list[Image.Image] = []

    for i, (box, label) in enumerate(zip(quadrants, labels)):
        print(f"\n[{i+1}/4] Quadrant {label} {box}")

        quad_img = src.crop(box)
        tmp_in = Path(f"/tmp/map_quad_{i}.png")
        tmp_out = Path(f"/tmp/map_quad_{i}_up.png")

        buf = io.BytesIO()
        quad_img.save(buf, format="PNG", optimize=False)
        size_mb = len(buf.getvalue()) / 1024 / 1024
        print(f"       Taille quadrant : {size_mb:.1f} Mo", end="")
        if size_mb > 10:
            print("  ⚠ > 10 Mo, passage en JPEG lossy pour respecter la limite API")
            buf = io.BytesIO()
            quad_img.save(buf, format="JPEG", quality=92)
            tmp_in = Path(f"/tmp/map_quad_{i}.jpg")
        else:
            print()

        tmp_in.write_bytes(buf.getvalue())

        upscale_image(tmp_in, tmp_out, factor=factor)
        upscaled_quadrants.append(Image.open(tmp_out).convert("RGB"))

    uw, uh = upscaled_quadrants[0].size
    print(f"\nRecomposition : quadrants upscalés {uw}×{uh} → image finale {uw*2}×{uh*2}")
    final = Image.new("RGB", (uw * 2, uh * 2))
    final.paste(upscaled_quadrants[0], (0,   0))
    final.paste(upscaled_quadrants[1], (uw,  0))
    final.paste(upscaled_quadrants[2], (0,   uh))
    final.paste(upscaled_quadrants[3], (uw,  uh))

    output_path.parent.mkdir(parents=True, exist_ok=True)
    final.save(output_path, format="PNG", optimize=False)
    print(f"\nSauvegardé : {output_path} ({output_path.stat().st_size / 1024 / 1024:.1f} Mo)")


def main() -> None:
    default_map = _backend / "static" / "MAP.png"
    parser = argparse.ArgumentParser(description="Upscale MAP.png en 4 quadrants via Vertex AI")
    parser.add_argument("--input",  type=Path, default=default_map)
    parser.add_argument("--output", type=Path, default=None)
    parser.add_argument("--factor", choices=("x2", "x4"), default="x2")
    args = parser.parse_args()

    out = args.output or args.input
    if not args.input.is_file():
        raise SystemExit(f"Fichier introuvable : {args.input}")

    upscale_map(args.input, out, factor=args.factor)


if __name__ == "__main__":
    main()