Files
DadaoTask/tools/make-icons.py
T
steven b3cd115bd9
CI / backend (push) Canceled after 0s
feat(design): 主色由墨松绿改为景泰蓝蓝系,Logo 与图标同步
纸白底改冷调与主色同轴;语义色 sage/wheat/rust 不变,sky 提亮与主色区分。Logo 三段线改浅蓝白、圆点改亮蓝;favicon/PWA 图标/安卓自适应图标/状态栏一并重绘,新增 tools/make-icons.py 作为唯一出处。
2026-11-01 18:48:26 +08:00

77 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""按 Web Logo(icons.tsx 的 <Logo/>)重绘 PWA 图标:景泰蓝底 + 三条浅蓝白线 + 一点亮蓝。
用法:python tools/make-icons.py
输出覆盖 web/public/icons/*.png(与 SVG 同一套比例:64 画布,rx=18,线宽 4,点半径 6)。
"""
from __future__ import annotations
from pathlib import Path
from PIL import Image, ImageDraw
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "web" / "public" / "icons"
BG = "#274B73"
LINE = "#EAF3FB"
DOT = "#5CA8E8"
SS = 8 # 超采样倍数,边缘才不毛
def draw(size: int, *, rounded: bool, inset: float = 0.0) -> Image.Image:
"""在 size×size 上画 logo。inset 是安全区留白比例(maskable 图标要留)。"""
big = size * SS
img = Image.new("RGBA", (big, big), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
if rounded:
d.rounded_rectangle([0, 0, big - 1, big - 1], radius=big * 18 / 64, fill=BG)
else:
d.rectangle([0, 0, big, big], fill=BG)
# 64 画布坐标 → 像素;inset 让图形整体缩小居中(给 maskable 留安全区)
scale = big / 64 * (1 - 2 * inset)
off = big * inset
def box(x: float, y: float) -> tuple[float, float]:
return off + x * scale, off + y * scale
stroke = max(1, round(4 * scale))
for y, x2 in ((23, 46), (32, 37), (41, 30)):
x1, yy = box(18, y)
d.line([x1, yy, *box(x2, y)], fill=LINE, width=stroke)
# 圆头:PIL 的 line 没有 cap,用小圆补两端
r = stroke / 2
for cx, cy in ((x1, yy), box(x2, y)):
d.ellipse([cx - r, cy - r, cx + r, cy + r], fill=LINE)
cx, cy = box(46, 41)
r = 6 * scale
d.ellipse([cx - r, cy - r, cx + r, cy + r], fill=DOT)
return img.resize((size, size), Image.LANCZOS)
def main() -> None:
OUT.mkdir(parents=True, exist_ok=True)
# 圆角版:favicon 之外的常规 PWA 图标
draw(192, rounded=True).save(OUT / "icon-192.png")
draw(512, rounded=True).save(OUT / "icon-512.png")
# iOS 会自己裁圆角,底图必须是方的
draw(180, rounded=False).save(OUT / "apple-touch-icon.png")
# maskable:图形缩进 12% 安全区
draw(512, rounded=False, inset=0.12).save(OUT / "maskable-512.png")
# 文档里引用的安卓图标预览
preview = ROOT / "2.Design" / "screens" / "android-icon-512.png"
preview.parent.mkdir(parents=True, exist_ok=True)
draw(512, rounded=True).save(preview)
for p in sorted(OUT.glob("*.png")):
print(p.relative_to(ROOT), Image.open(p).size)
print(preview.relative_to(ROOT), Image.open(preview).size)
if __name__ == "__main__":
main()