| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- # -*- coding: utf-8 -*-
- """Generate Ai-DOP tabBar icons: 81x81 PNG, transparent bg, two states (gray / navy)."""
- import math
- from PIL import Image, ImageDraw
- S = 4 # supersample
- SIZE = 81 * S
- OUT = r"d:\Projects\Ai-DOP\SourceCode\ZZYDOP\App\src\static\tab"
- GRAY = (144, 147, 153, 255) # #909399
- NAVY = (47, 58, 82, 255) # #2F3A52
- def canvas():
- img = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0))
- return img, ImageDraw.Draw(img)
- def save(img, name):
- import os
- os.makedirs(OUT, exist_ok=True)
- img = img.resize((81, 81), Image.LANCZOS)
- img.save(os.path.join(OUT, name))
- def lw(w):
- return int(w * S)
- # ---------- home: house ----------
- def draw_home(color):
- img, d = canvas()
- c = SIZE / 2
- roof_top = 14 * S
- roof_half = 30 * S
- roof_y = 40 * S
- # roof (triangle outline via polygon)
- d.polygon([(c, roof_top), (c - roof_half, roof_y), (c + roof_half, roof_y)], fill=color)
- # body
- bx0, by0 = c - 22 * S, 42 * S
- bx1, by1 = c + 22 * S, 68 * S
- d.rectangle([bx0, by0, bx1, by1], fill=color)
- # door cutout
- dw = 9 * S
- d.rectangle([c - dw, 52 * S, c + dw, by1], fill=(0, 0, 0, 0))
- return img
- # ---------- todo: clipboard with check ----------
- def draw_todo(color):
- img, d = canvas()
- x0, y0, x1, y1 = 18 * S, 14 * S, 63 * S, 70 * S
- w = lw(4)
- # board outline (rounded approximated by rectangle)
- d.rectangle([x0, y0 + 4 * S, x1, y1], outline=color, width=w)
- # clip
- d.rectangle([30 * S, 10 * S, 51 * S, 20 * S], fill=color)
- # check mark
- pts = [(26 * S, 44 * S), (37 * S, 56 * S), (57 * S, 30 * S)]
- d.line(pts, fill=color, width=lw(5), joint="curve")
- return img
- # ---------- message: chat bubble ----------
- def draw_message(color):
- img, d = canvas()
- x0, y0, x1, y1 = 13 * S, 16 * S, 68 * S, 56 * S
- r = 10 * S
- d.rounded_rectangle([x0, y0, x1, y1], radius=r, fill=color)
- # tail
- d.polygon([(26 * S, y1 - 2 * S), (26 * S, 72 * S), (42 * S, y1 - 2 * S)], fill=color)
- # dots
- for i in range(3):
- cx = (27 + i * 13.5) * S
- cy = (y0 + y1) / 2
- rr = 3.2 * S
- d.ellipse([cx - rr, cy - rr, cx + rr, cy + rr], fill=(0, 0, 0, 0))
- return img
- # ---------- mine: person ----------
- def draw_mine(color):
- img, d = canvas()
- c = SIZE / 2
- # head
- hr = 12 * S
- hy = 28 * S
- d.ellipse([c - hr, hy - hr, c + hr, hy + hr], fill=color)
- # shoulders (half ellipse)
- sw = 26 * S
- sy0 = 46 * S
- sy1 = 88 * S
- d.pieslice([c - sw, sy0, c + sw, sy1], start=180, end=360, fill=color)
- d.rectangle([c - sw, (sy0 + sy1) / 2, c + sw, sy1], fill=(0, 0, 0, 0))
- # re-draw shoulders as chord + body rect to horizon
- d.pieslice([c - sw, sy0, c + sw, sy1], start=180, end=360, fill=color)
- return img
- def main():
- variants = {"": GRAY, "-active": NAVY}
- drawers = {"home": draw_home, "todo": draw_todo, "message": draw_message, "mine": draw_mine}
- for name, fn in drawers.items():
- for suffix, color in variants.items():
- save(fn(color), f"{name}{suffix}.png")
- print("done")
- if __name__ == "__main__":
- main()
|