-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_icon.py
More file actions
113 lines (88 loc) · 3.9 KB
/
Copy pathmake_icon.py
File metadata and controls
113 lines (88 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""Генератор иконки-снежинки для Криостат.
Рисует 6-лучевую снежинку с боковыми ответвлениями на круглой
тёмно-синей подложке и сохраняет многоразмерный icon.ico
(16/32/48/64/128/256) рядом со скриптом.
Запуск: python make_icon.py
"""
from __future__ import annotations
import math
import os
from PIL import Image, ImageDraw
# Цвета (морозная палитра)
BG_OUTER = (13, 27, 42) # тёмно-синий фон круга
BG_INNER = (27, 56, 92) # центр круга чуть светлее
SNOW = (224, 244, 255) # лёд/снег почти белый
SNOW_HI = (255, 255, 255) # блик в центре
def _lerp(a, b, t):
return tuple(int(a[i] + (b[i] - a[i]) * t) for i in range(3))
def draw_snowflake(size: int) -> Image.Image:
"""Возвращает RGBA-изображение снежинки size×size."""
# Рисуем в 4× для сглаживания, потом уменьшаем
S = size * 4
img = Image.new("RGBA", (S, S), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
cx = cy = S / 2
R = S * 0.46
# Радиальный фон-круг (имитация градиента кольцами)
rings = 48
for i in range(rings, 0, -1):
t = i / rings
col = _lerp(BG_INNER, BG_OUTER, t)
rr = R * t
d.ellipse([cx - rr, cy - rr, cx + rr, cy + rr], fill=col + (255,))
# Тонкое ледяное кольцо по краю
d.ellipse([cx - R, cy - R, cx + R, cy + R],
outline=SNOW + (90,), width=max(1, S // 200))
arm_len = R * 0.80
main_w = max(2, int(S * 0.022))
branch_w = max(2, int(S * 0.015))
def rot(px, py, ang):
s, c = math.sin(ang), math.cos(ang)
return (cx + px * c - py * s, cy + px * s + py * c)
for k in range(6):
ang = math.pi / 3 * k
# Главный луч (от центра вверх в локальных координатах)
x0, y0 = rot(0, 0, ang)
x1, y1 = rot(0, -arm_len, ang)
d.line([x0, y0, x1, y1], fill=SNOW + (255,),
width=main_w)
# Боковые «ёлочки» — по 3 пары ответвлений
for frac, blen in ((0.42, 0.26), (0.62, 0.20), (0.80, 0.13)):
bx, by = 0, -arm_len * frac
bl = arm_len * blen
for sgn in (-1, 1):
ex = bx + sgn * bl * math.cos(math.radians(35))
ey = by + bl * math.sin(math.radians(35))
p0 = rot(bx, by, ang)
p1 = rot(ex, ey, ang)
d.line([p0[0], p0[1], p1[0], p1[1]],
fill=SNOW + (255,), width=branch_w)
# Маленький ромб на конце луча
tip = arm_len
dd = arm_len * 0.07
pts = [rot(0, -tip - dd, ang), rot(dd, -tip, ang),
rot(0, -tip + dd, ang), rot(-dd, -tip, ang)]
d.polygon(pts, fill=SNOW + (255,))
# Центральная «звезда»-узел
cr = arm_len * 0.16
d.ellipse([cx - cr, cy - cr, cx + cr, cy + cr], fill=SNOW + (255,))
cr2 = cr * 0.5
d.ellipse([cx - cr2, cy - cr2, cx + cr2, cy + cr2],
fill=SNOW_HI + (255,))
return img.resize((size, size), Image.LANCZOS)
def main() -> None:
here = os.path.dirname(os.path.abspath(__file__))
sizes = [16, 32, 48, 64, 128, 256]
frames = [draw_snowflake(s) for s in sizes]
ico_path = os.path.join(here, "icon.ico")
frames[-1].save(
ico_path, format="ICO",
sizes=[(s, s) for s in sizes],
)
# Дополнительно PNG 256 — для README/релиза
png_path = os.path.join(here, "icon.png")
frames[-1].save(png_path, format="PNG")
print(f"OK: {ico_path}")
print(f"OK: {png_path}")
if __name__ == "__main__":
main()