- static/appIcon.png: 重绘 1024x1024 图标(冰蓝渐变底 + 白色制冷杯 + 雪花标志 + 蓝牙角标), 生成脚本 .icon_build/make_icon.py(Pillow,4x 超采样) - manifest.json: name 改 SmartAssister;modules 增加 Bluetooth(自定义基座必需); 删除手工声明的 4 个蓝牙权限(模块自动注入,避免 AndroidManifest 合并冲突) - docs: 追加修改记录_2026-09-09_App图标更换为制冷杯主题.md
117 lines
3.5 KiB
Python
117 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# 生成 App 图标:制冷杯 + 蓝牙徽标
|
|
import math, sys
|
|
sys.path.insert(0, '.icon_build')
|
|
from PIL import Image, ImageDraw
|
|
|
|
S = 4 # 超采样倍数
|
|
N = 1024 # 目标尺寸
|
|
W = N * S
|
|
|
|
def sc(v):
|
|
return int(round(v * S))
|
|
|
|
# ---------- 背景:冰蓝纵向渐变 ----------
|
|
top = (110, 200, 235) # 浅冰蓝
|
|
bot = (24, 82, 152) # 深蓝
|
|
grad = Image.new('RGB', (1, 2))
|
|
grad.putpixel((0, 0), top)
|
|
grad.putpixel((0, 1), bot)
|
|
grad = grad.resize((W, W), Image.BICUBIC)
|
|
|
|
img = Image.new('RGBA', (W, W), (0, 0, 0, 0))
|
|
|
|
# 圆角矩形蒙版(角透明,与旧图标一致)
|
|
mask = Image.new('L', (W, W), 0)
|
|
md = ImageDraw.Draw(mask)
|
|
md.rounded_rectangle([0, 0, W - 1, W - 1], radius=sc(230), fill=255)
|
|
img.paste(grad, (0, 0), mask)
|
|
|
|
d = ImageDraw.Draw(img)
|
|
|
|
def thick_line(pts, color, width):
|
|
d.line(pts, fill=color, width=width, joint='curve')
|
|
r = width // 2
|
|
for (x, y) in (pts[0], pts[-1]):
|
|
d.ellipse([x - r, y - r, x + r, y + r], fill=color)
|
|
|
|
def rpoly(pts, r, color):
|
|
"""多边形 + 顶点圆角"""
|
|
d.polygon(pts, fill=color)
|
|
for (x, y) in pts:
|
|
d.ellipse([x - r, y - r, x + r, y + r], fill=color)
|
|
|
|
# ---------- 杯子 ----------
|
|
WHITE = (255, 255, 255, 255)
|
|
cx = 462
|
|
|
|
# 杯盖(圆角矩形,略宽于杯身)
|
|
lid = [sc(cx - 138), sc(240), sc(cx + 138), sc(330)]
|
|
d.rounded_rectangle(lid, radius=sc(32), fill=WHITE)
|
|
# 盖顶小凸起(冷感模块)
|
|
d.rounded_rectangle([sc(cx - 46), sc(196), sc(cx + 46), sc(250)],
|
|
radius=sc(22), fill=WHITE)
|
|
|
|
# 杯身(梯形,上宽下窄;仅顶部顶点补圆角,底部由圆角矩形收边)
|
|
body = [(sc(cx - 128), sc(316)),
|
|
(sc(cx + 128), sc(316)),
|
|
(sc(cx + 96), sc(712)),
|
|
(sc(cx - 96), sc(712))]
|
|
d.polygon(body, fill=WHITE)
|
|
tr = sc(14)
|
|
for (x, y) in (body[0], body[1]):
|
|
d.ellipse([x - tr, y - tr, x + tr, y + tr], fill=WHITE)
|
|
|
|
# 杯底圆角收边
|
|
d.rounded_rectangle([sc(cx - 100), sc(648), sc(cx + 100), sc(716)],
|
|
radius=sc(30), fill=WHITE)
|
|
|
|
# ---------- 雪花标志(杯身正面) ----------
|
|
SNOW = (39, 122, 190, 255)
|
|
fx, fy = sc(cx), sc(500)
|
|
arm = sc(78)
|
|
lw = sc(17)
|
|
br = sc(36) # 分叉长度
|
|
bpos = 0.62 # 分叉位置(沿臂比例)
|
|
|
|
# 中心圆点
|
|
cr = sc(14)
|
|
d.ellipse([fx - cr, fy - cr, fx + cr, fy + cr], fill=SNOW)
|
|
|
|
for k in range(6):
|
|
a = math.radians(k * 60 + 90)
|
|
dx, dy = math.cos(a), math.sin(a)
|
|
ex, ey = fx + dx * arm, fy + dy * arm
|
|
thick_line([(fx, fy), (ex, ey)], SNOW, lw)
|
|
# 每个臂上分叉
|
|
bx0, by0 = fx + dx * arm * bpos, fy + dy * arm * bpos
|
|
for sgn in (-1, 1):
|
|
ba = a + sgn * math.radians(55)
|
|
bex, bey = bx0 + math.cos(ba) * br, by0 + math.sin(ba) * br
|
|
thick_line([(bx0, by0), (bex, bey)], SNOW, lw)
|
|
|
|
# ---------- 蓝牙徽标(右下角白圆) ----------
|
|
bcx, bcy = sc(738), sc(742)
|
|
brad = sc(182)
|
|
d.ellipse([bcx - brad, bcy - brad, bcx + brad, bcy + brad], fill=WHITE)
|
|
|
|
RUNE = (24, 82, 152, 255)
|
|
a_ = sc(100) # 半高
|
|
d_ = sc(58) # 右伸距离
|
|
lw2 = sc(32)
|
|
p_top = (bcx, bcy - a_)
|
|
p_mid = (bcx, bcy)
|
|
p_bot = (bcx, bcy + a_)
|
|
p_ru = (bcx + d_, bcy - a_ // 2)
|
|
p_rl = (bcx + d_, bcy + a_ // 2)
|
|
p_lu = (bcx - d_, bcy - a_ // 2)
|
|
p_ll = (bcx - d_, bcy + a_ // 2)
|
|
for seg in ([p_top, p_bot], [p_top, p_ru, p_mid], [p_mid, p_rl, p_bot],
|
|
[p_lu, p_rl], [p_ll, p_ru]):
|
|
thick_line(seg, RUNE, lw2)
|
|
|
|
# ---------- 输出 ----------
|
|
out = img.resize((N, N), Image.LANCZOS)
|
|
out.save('static/appIcon.png')
|
|
print('saved static/appIcon.png')
|