Files
ctbjrj/tools/make_icon.py
T

88 lines
3.2 KiB
Python

# -*- coding: utf-8 -*-
"""
成套报价软件图标生成器 —— 与 app.svg 设计稿完全等价的 Pillow 绘制。
纯 Python + Pillow,零原生依赖(本机没有 cairo,SVG 无法直接栅格化)。
设计:深蓝→青蓝渐变圆角底 + 白色开关柜轮廓 + 三根铜排 + 绿色 ¥ 角标。
512 高分辨率绘制后缩放出多尺寸 app.ico,保证 16px 也清晰。
"""
import os
import math
from PIL import Image, ImageDraw
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
OUT_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, "..", "成套报价软件"))
ICO_PATH = os.path.join(OUT_DIR, "app.ico")
PNG_PATH = os.path.join(OUT_DIR, "app_512.png")
SIZES = [16, 32, 48, 64, 128, 256]
RENDER = 512 # 与 SVG viewBox 一致,坐标 1:1
def lerp(c1, c2, t):
return (int(c1[0] + (c2[0] - c1[0]) * t),
int(c1[1] + (c2[1] - c1[1]) * t),
int(c1[2] + (c2[2] - c1[2]) * t))
def rounded_gradient_rect(img, box, c_top, c_bot, radius):
"""垂直渐变圆角矩形(逐行渐变 + 圆角 mask)。"""
x0, y0, x1, y1 = box
w, h = x1 - x0, y1 - y0
grad = Image.new("RGBA", (w, h), (0, 0, 0, 0))
gp = grad.load()
for y in range(h):
c = lerp(c_top, c_bot, y / max(h - 1, 1))
for x in range(w):
gp[x, y] = (c[0], c[1], c[2], 255)
mask = Image.new("L", (w, h), 0)
ImageDraw.Draw(mask).rounded_rectangle([0, 0, w - 1, h - 1], radius=radius, fill=255)
img.paste(grad, (x0, y0), mask)
def line_round(draw, p1, p2, width, fill):
"""带圆头的粗线。"""
draw.line([p1, p2], fill=fill, width=width)
r = width / 2.0
for p in (p1, p2):
draw.ellipse([p[0] - r, p[1] - r, p[0] + r, p[1] + r], fill=fill)
def main():
img = Image.new("RGBA", (RENDER, RENDER), (0, 0, 0, 0))
d = ImageDraw.Draw(img)
# 1) 渐变圆角背景 (16,16)-(496,496) r=100,#1d4ed8→#0e7490
rounded_gradient_rect(img, (16, 16, 496, 496), (29, 78, 216), (14, 116, 144), 100)
d = ImageDraw.Draw(img)
# 2) 开关柜轮廓 (118,88)-(394,392) r=30 白色描边 24
d.rounded_rectangle([118, 88, 394, 392], radius=30, outline=(255, 255, 255, 255), width=24)
# 3) 三根铜排 (160..352),高 34,r=9,铜色渐变近似为纯色+顶部亮色高光线
for y in (138, 218, 298):
d.rounded_rectangle([160, y, 352, y + 34], radius=9, fill=(234, 141, 25, 255)) # #ea8d19 主体
d.rounded_rectangle([160, y, 352, y + 14], radius=7, fill=(251, 191, 36, 255)) # #fbbf24 顶部亮
# 4) ¥ 角标:绿圆 (376,376) r=94 + 白描边 14
d.ellipse([376 - 94, 376 - 94, 376 + 94, 376 + 94],
fill=(16, 185, 129, 255), outline=(255, 255, 255, 255), width=14)
# ¥ 笔画(白,线宽 19,圆头)
W = (255, 255, 255, 255)
lw = 19
line_round(d, (338, 338), (378, 380), lw, W) # 撇
line_round(d, (416, 338), (376, 380), lw, W) # 捺
line_round(d, (340, 392), (412, 392), lw, W) # 上横
line_round(d, (340, 420), (412, 420), lw, W) # 下横
line_round(d, (377, 414), (377, 442), lw, W) # 竖
# 5) 导出:512 PNG 预览 + 多尺寸 ICO
img.save(PNG_PATH)
img.save(ICO_PATH, sizes=[(s, s) for s in SIZES])
print("已生成:", ICO_PATH)
print("已生成:", PNG_PATH)
if __name__ == "__main__":
main()