#!/usr/bin/env python3 """Downsizes res/app_icon_50x50_64_color.png into watch/resources/app_icon.png. Pebble's own build tooling (process_sdk_resources.py) hard-fails any "menuIcon": true resource larger than 25x25px - the fixed size Pebble OS renders app icons at in the watch's own app launcher list (and, synced from the watch, in the mobile app's installed-apps list too). The source art in res/ is 50x50 (square, so it downsamples to exactly 25x25 with no letterboxing) - the color variant is used, per the same "prefer color" choice as the rest of this app's card art, over the companion *_gray.png fallback also present in res/. Generated output, like i18n_tables.auto.c and resources/img/*.png - not committed (see .gitignore), regenerate by running this script directly or via `pebble build` (wired into wscript alongside gen_card_images.py). Requires Pillow (`pip install Pillow`), not part of this repo's own desktop build/test toolchain. """ import os import sys from PIL import Image SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SRC_PATH = os.path.normpath( os.path.join(SCRIPT_DIR, "..", "..", "res", "app_icon_50x50_64_color.png") ) OUT_PATH = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "resources", "app_icon.png")) MAX_ICON_SIZE = 25 # Pebble's own hard cap for "menuIcon": true resources. def main(): if os.path.exists(OUT_PATH) and os.path.getmtime(OUT_PATH) >= os.path.getmtime(SRC_PATH): print(f"{OUT_PATH} already up to date", file=sys.stderr) return os.makedirs(os.path.dirname(OUT_PATH), exist_ok=True) with Image.open(SRC_PATH) as img: ratio = MAX_ICON_SIZE / max(img.width, img.height) size = (round(img.width * ratio), round(img.height * ratio)) resized = img.convert("RGBA").resize(size, Image.LANCZOS) resized.save(OUT_PATH, "PNG", optimize=True) print(f"wrote {OUT_PATH} ({size[0]}x{size[1]})", file=sys.stderr) if __name__ == "__main__": main()