from PIL import Image, ImageDraw, ImageFont import os def draw_icon(target_sz): sc = 4 sz = target_sz * sc img = Image.new("RGBA", (sz, sz), (0, 0, 0, 0)) d = ImageDraw.Draw(img) m = max(int(sz * 0.06), 2) d.rounded_rectangle( [m, m, sz - m - 1, sz - m - 1], radius=int(sz * 0.20), fill=(30, 30, 30, 255)) GREEN = (120, 140, 50) WHITE = (245, 245, 245) cx, cy = sz / 2, sz / 2 r = sz * 0.14 ncx = cx + sz * 0.04 ncy = cy + sz * 0.20 d.ellipse([ncx - r * 1.25, ncy - r * 0.85, ncx + r * 1.25, ncy + r * 0.85], fill=GREEN) stem_w = max(int(sz * 0.05), 2) stem_x = ncx + r * 1.1 - stem_w stem_top = cy - sz * 0.30 d.rectangle([stem_x, stem_top, stem_x + stem_w, ncy - r * 0.2], fill=GREEN) flag_h = int(sz * 0.22) flag_w = sz * 0.20 for i in range(flag_h): frac = i / flag_h w = flag_w * (1.0 - frac * 0.5) y = stem_top + i d.rectangle([stem_x + stem_w, y, stem_x + stem_w + w, y + 1], fill=GREEN) try: fs = max(int(sz * 0.28), 12) fnt = ImageFont.truetype("arialbd.ttf", fs) except Exception: try: fnt = ImageFont.truetype("arial.ttf", max(int(sz * 0.28), 12)) except Exception: fnt = ImageFont.load_default() bb = d.textbbox((0, 0), "S", font=fnt) tw, th = bb[2] - bb[0], bb[3] - bb[1] tx = cx - tw / 2 - sz * 0.15 ty = cy - th / 2 - sz * 0.06 d.text((tx, ty), "S", fill=WHITE, font=fnt) return img.resize((target_sz, target_sz), Image.LANCZOS) sizes = [16, 24, 32, 48, 64, 128, 256] images = [draw_icon(s) for s in sizes] ico_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "app.ico") images[-1].save( ico_path, format="ICO", sizes=[(s, s) for s in sizes], append_images=images[:-1]) preview = os.path.join(os.path.dirname(os.path.abspath(__file__)), "app_preview.png") images[-1].save(preview) print(f"ICO: {os.path.getsize(ico_path)} bytes, {len(sizes)} sizes") print("Done")