Files
xianyan/Scripts/generate_tray_icons.py
Developer 6119918185 release: bump version to 6.6.25+2606241
主要变更:
1. 新增桌面端托盘图标支持深色/浅色主题切换
2. 重构应用锁、动画配置、小组件导航服务职责
3. 修复Riverpod初始化断言、防重复点击、工作台模式残留选中态问题
4. 优化诗词服务、阅读进度、搜索结果空状态体验
5. 完善macOS打包配置与错误静默处理逻辑
6. 新增快速卡片多语言适配与动画退出队列管理
2026-06-24 04:26:50 +08:00

158 lines
5.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.
#!/usr/bin/env python3
"""
闲言APP — 系统托盘图标生成脚本
创建时间: 2026-06-18
更新时间: 2026-06-22
作用: 用 Pillow 生成 macOS/Windows 托盘图标 PNG + ICO浅色+深色两套)
设计: 对话气泡 + 三条横线,体现"记录言语"主题
输出:
- assets/images/tray_icon_light.png (黑色图标,用于 macOS template + Win 浅色主题)
- assets/images/tray_icon_dark.png (白色图标,用于 Win 深色主题)
- assets/images/tray_icon_light_32.png (32x32 高清版)
- assets/images/tray_icon_dark_32.png (32x32 高清版)
- windows/runner/resources/tray_icon_light.ico (黑色图标Win 浅色主题)
- windows/runner/resources/tray_icon_dark.ico (白色图标Win 深色/纯黑主题)
"""
import os
from PIL import Image, ImageDraw
# ============================================================
# 配置
# ============================================================
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OUTPUT_DIR = os.path.join(PROJECT_ROOT, 'assets', 'images')
WIN_ICO_DIR = os.path.join(PROJECT_ROOT, 'windows', 'runner', 'resources')
SIZES = [16, 32] # 生成 16x16 和 32x32 两种尺寸
ICO_SIZES = [16, 24, 32, 48, 64] # ICO 文件包含多种尺寸
# 颜色定义
COLOR_LIGHT = (0, 0, 0, 255) # 黑色(浅色主题用)
COLOR_DARK = (255, 255, 255, 255) # 白色(深色主题用)
COLOR_TRANSPARENT = (0, 0, 0, 0)
def draw_tray_icon(size: int, color: tuple) -> Image.Image:
"""绘制托盘图标
设计:
- 对话气泡(圆角矩形)+ 三条横线 + 气泡尾巴
- 单色设计,简洁现代
"""
# 创建透明背景
img = Image.new('RGBA', (size, size), COLOR_TRANSPARENT)
draw = ImageDraw.Draw(img)
# 缩放因子(基于 16x16 设计)
scale = size / 16.0
def s(v):
"""缩放坐标"""
return int(v * scale)
# ============================================================
# 1. 对话气泡主体(圆角矩形)
# ============================================================
# 气泡位置:左上 (1, 1) 到右下 (15, 11)
bubble_x1, bubble_y1 = s(1), s(1)
bubble_x2, bubble_y2 = s(15), s(11)
bubble_radius = s(2)
# 绘制圆角矩形气泡
draw.rounded_rectangle(
[bubble_x1, bubble_y1, bubble_x2, bubble_y2],
radius=bubble_radius,
fill=color,
)
# ============================================================
# 2. 气泡尾巴(左下角,指向说话者)
# ============================================================
tail_points = [
(s(3), s(11)), # 尾巴起点(气泡底部)
(s(3), s(14)), # 尾巴尖
(s(6), s(11)), # 尾巴终点(气泡底部)
]
draw.polygon(tail_points, fill=color)
# ============================================================
# 3. 气泡内三条横线(代表文字)
# ============================================================
line_color = COLOR_TRANSPARENT # 用透明色"挖出"横线
line_thickness = max(1, s(1))
# 三条横线的位置(在气泡内部居中)
line_x1 = s(3)
line_x2_short = s(10) # 短线结束
line_x2_long = s(13) # 长线结束
# 第一条横线(短)
draw.rectangle(
[line_x1, s(4), line_x2_short, s(4) + line_thickness - 1],
fill=line_color,
)
# 第二条横线(长)
draw.rectangle(
[line_x1, s(6), line_x2_long, s(6) + line_thickness - 1],
fill=line_color,
)
# 第三条横线(中)
draw.rectangle(
[line_x1, s(8), s(11), s(8) + line_thickness - 1],
fill=line_color,
)
return img
def main():
"""主函数:生成所有图标"""
os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(WIN_ICO_DIR, exist_ok=True)
for size in SIZES:
# 浅色版(黑色图标)
light_img = draw_tray_icon(size, COLOR_LIGHT)
light_name = f'tray_icon_light{"" if size == 16 else f"_{size}"}.png'
light_path = os.path.join(OUTPUT_DIR, light_name)
light_img.save(light_path, 'PNG')
print(f'✅ 生成: {light_path} ({size}x{size})')
# 深色版(白色图标)
dark_img = draw_tray_icon(size, COLOR_DARK)
dark_name = f'tray_icon_dark{"" if size == 16 else f"_{size}"}.png'
dark_path = os.path.join(OUTPUT_DIR, dark_name)
dark_img.save(dark_path, 'PNG')
print(f'✅ 生成: {dark_path} ({size}x{size})')
# ============================================================
# 生成 Windows ICO 文件(包含多尺寸)
# ============================================================
# 浅色 ICO黑色图标白天模式用
light_ico_images = [draw_tray_icon(s, COLOR_LIGHT) for s in ICO_SIZES]
light_ico_path = os.path.join(WIN_ICO_DIR, 'tray_icon_light.ico')
light_ico_images[0].save(
light_ico_path,
format='ICO',
sizes=[(s, s) for s in ICO_SIZES],
append_images=light_ico_images[1:],
)
print(f'✅ 生成: {light_ico_path} (ICO 多尺寸)')
# 深色 ICO白色图标深色/纯黑模式用)
dark_ico_images = [draw_tray_icon(s, COLOR_DARK) for s in ICO_SIZES]
dark_ico_path = os.path.join(WIN_ICO_DIR, 'tray_icon_dark.ico')
dark_ico_images[0].save(
dark_ico_path,
format='ICO',
sizes=[(s, s) for s in ICO_SIZES],
append_images=dark_ico_images[1:],
)
print(f'✅ 生成: {dark_ico_path} (ICO 多尺寸)')
print('\n🎉 所有托盘图标生成完成!')
if __name__ == '__main__':
main()