"""Generate icon files for NotifyPulse from a photo (no more blue placeholder). Drop your desired square-ish image in icon.png, then run: python make_ico.py """ from pathlib import Path from PIL import Image SIZES_PWA = (192, 512) SIZES_ICO = (256, 128, 64, 48, 32, 16) def load_base(img_path: Path) -> Image.Image: if not img_path.exists(): raise FileNotFoundError(f"Source image not found: {img_path}") img = Image.open(img_path).convert("RGBA") # Centre-crop to square so the icon fills evenly. w, h = img.size side = min(w, h) left = (w - side) // 2 top = (h - side) // 2 img = img.crop((left, top, left + side, top + side)) return img def save_resized(img: Image.Image, size: int, dest: Path): resized = img.resize((size, size), Image.Resampling.LANCZOS) dest.parent.mkdir(parents=True, exist_ok=True) resized.save(dest, format="PNG") def main(): here = Path(__file__).parent src = here / "icon.png" base = load_base(src) # PWA icons for sz in SIZES_PWA: save_resized(base, sz, here / "pwa" / f"icon-{sz}.png") # Multi-resolution .ico for PyInstaller / Windows (uses same photo) ico_frames = [base.resize((s, s), Image.Resampling.LANCZOS) for s in SIZES_ICO] ico_path = here / "icon.ico" ico_frames[0].save( ico_path, format="ICO", sizes=[(s, s) for s in SIZES_ICO], append_images=ico_frames[1:], ) print("Icons generated from icon.png:") print(" pwa/icon-192.png, pwa/icon-512.png") print(f" {ico_path.name} (multi-size)") if __name__ == "__main__": main()