102 lines
3.0 KiB
Python
102 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
optimize_web_resources.py - Resize PNG images for the web build.
|
|
|
|
Copies <src> to <dst>/resources/, then downscales all PNG files:
|
|
- resources/w/ui/img/** -> 1/8 original size
|
|
- all other PNGs -> 1/4 original size
|
|
|
|
Files listed in EXCEPTIONS are copied unchanged.
|
|
|
|
Usage (manual):
|
|
python optimize_web_resources.py [--src resources] [--dst web_resources]
|
|
|
|
Usage (CMake):
|
|
${Python3_EXECUTABLE} optimize_web_resources.py --src <abs_src> --dst <abs_dst>
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
|
|
try:
|
|
from PIL import Image
|
|
except ImportError:
|
|
raise SystemExit("Pillow is required: pip install Pillow")
|
|
|
|
# Paths relative to the resources directory — these files are never resized.
|
|
EXCEPTIONS = {
|
|
"loading.png",
|
|
"black.png",
|
|
}
|
|
|
|
# Path prefixes (relative to resources root, forward-slash) that get 8x reduction.
|
|
HIGH_REDUCTION_PREFIXES = (
|
|
"w/ui/img",
|
|
)
|
|
|
|
|
|
def _resize_factor(rel: str) -> int:
|
|
norm = rel.replace("\\", "/")
|
|
for prefix in HIGH_REDUCTION_PREFIXES:
|
|
if norm.startswith(prefix):
|
|
return 8
|
|
return 4
|
|
|
|
|
|
def _next_pot(n: int) -> int:
|
|
if n < 1:
|
|
return 1
|
|
p = 1
|
|
while p < n:
|
|
p <<= 1
|
|
return p
|
|
|
|
|
|
def optimize(src_dir: str, dst_parent: str) -> None:
|
|
src_dir = os.path.abspath(src_dir)
|
|
dst_resources = os.path.join(os.path.abspath(dst_parent), "resources")
|
|
|
|
print(f"Copying {src_dir} -> {dst_resources}")
|
|
if os.path.exists(dst_resources):
|
|
shutil.rmtree(dst_resources)
|
|
shutil.copytree(src_dir, dst_resources)
|
|
|
|
total = 0
|
|
for root, _dirs, files in os.walk(dst_resources):
|
|
for filename in files:
|
|
if not filename.lower().endswith(".png"):
|
|
continue
|
|
|
|
full_path = os.path.join(root, filename)
|
|
rel = os.path.relpath(full_path, dst_resources).replace("\\", "/")
|
|
|
|
if rel in EXCEPTIONS:
|
|
print(f" skip (exception): {rel}")
|
|
continue
|
|
|
|
factor = _resize_factor(rel)
|
|
|
|
with Image.open(full_path) as img:
|
|
orig_w, orig_h = img.size
|
|
new_w = _next_pot(max(1, orig_w // factor))
|
|
new_h = _next_pot(max(1, orig_h // factor))
|
|
resized = img.resize((new_w, new_h), Image.LANCZOS)
|
|
resized.save(full_path)
|
|
|
|
print(f" {rel}: {orig_w}x{orig_h} -> {new_w}x{new_h} (/{factor} + POT)")
|
|
total += 1
|
|
|
|
print(f"Done. Resized {total} PNG file(s).")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description="Optimize PNG images for web build")
|
|
parser.add_argument("--src", default="resources",
|
|
help="Source resources directory (default: resources)")
|
|
parser.add_argument("--dst", default="web_resources",
|
|
help="Destination parent directory; will contain a 'resources' subdir "
|
|
"(default: web_resources)")
|
|
args = parser.parse_args()
|
|
optimize(args.src, args.dst)
|