Skip to content

Commit 65983d0

Browse files
authored
Create generate_icon.py
1 parent 0d84ae5 commit 65983d0

1 file changed

Lines changed: 200 additions & 0 deletions

File tree

generate_icon.py

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
"""
4+
生成程序图标
5+
支持 Windows (.ico) 和 macOS (.icns)
6+
"""
7+
8+
import sys
9+
from pathlib import Path
10+
11+
try:
12+
from PyQt5.QtWidgets import QApplication
13+
from PyQt5.QtGui import QIcon, QPixmap, QPainter, QColor
14+
from PyQt5.QtCore import QSize, Qt
15+
except ImportError:
16+
print("错误: 需要安装 PyQt5")
17+
print("安装命令: pip install PyQt5")
18+
sys.exit(1)
19+
20+
21+
def create_matrix_icon_pixmap(size):
22+
"""创建指定尺寸的图标"""
23+
pixmap = QPixmap(size, size)
24+
pixmap.fill(QColor(0, 0, 0)) # 黑色背景
25+
26+
painter = QPainter(pixmap)
27+
painter.setRenderHint(QPainter.Antialiasing)
28+
29+
# 绘制绿色边框
30+
painter.setPen(QColor(0, 255, 65)) # 矩阵绿
31+
painter.setBrush(Qt.NoBrush)
32+
border_width = max(2, size // 16)
33+
painter.drawRect(border_width, border_width, size - border_width * 2, size - border_width * 2)
34+
35+
# 绘制内部装饰(矩阵代码风格)
36+
if size >= 32:
37+
# 绘制对角线
38+
if size >= 48:
39+
painter.setPen(QColor(0, 255, 65))
40+
margin = size // 8
41+
painter.drawLine(margin, margin, size - margin, size - margin)
42+
painter.drawLine(size - margin, margin, margin, size - margin)
43+
44+
# 绘制中心点
45+
center = size // 2
46+
painter.setBrush(QColor(0, 255, 65))
47+
dot_size = max(2, size // 16)
48+
painter.drawEllipse(center - dot_size, center - dot_size, dot_size * 2, dot_size * 2)
49+
50+
# 绘制一些装饰线条
51+
if size >= 64:
52+
# 绘制四个角的装饰
53+
corner_size = size // 4
54+
painter.setPen(QColor(0, 200, 50)) # 稍暗的绿色
55+
margin = size // 16
56+
# 左上角
57+
painter.drawLine(margin, margin, corner_size, margin)
58+
painter.drawLine(margin, margin, margin, corner_size)
59+
# 右上角
60+
painter.drawLine(size - margin, margin, size - corner_size, margin)
61+
painter.drawLine(size - margin, margin, size - margin, corner_size)
62+
# 左下角
63+
painter.drawLine(margin, size - margin, corner_size, size - margin)
64+
painter.drawLine(margin, size - margin, margin, size - corner_size)
65+
# 右下角
66+
painter.drawLine(size - margin, size - margin, size - corner_size, size - margin)
67+
painter.drawLine(size - margin, size - margin, size - margin, size - corner_size)
68+
69+
painter.end()
70+
return pixmap
71+
72+
73+
def create_ico_file(output_path):
74+
"""创建 Windows .ico 文件"""
75+
try:
76+
# 尝试使用 PIL/Pillow 创建 ICO 文件
77+
from PIL import Image
78+
79+
# 创建多个尺寸的图标
80+
images = []
81+
sizes = [16, 32, 48, 64, 128, 256]
82+
83+
for size in sizes:
84+
pixmap = create_matrix_icon_pixmap(size)
85+
# 转换为 PIL Image
86+
qimage = pixmap.toImage()
87+
width = qimage.width()
88+
height = qimage.height()
89+
ptr = qimage.bits()
90+
ptr.setsize(qimage.byteCount())
91+
arr = bytes(ptr)
92+
pil_image = Image.frombuffer('RGBA', (width, height), arr, 'raw', 'BGRA', 0, 1)
93+
images.append(pil_image)
94+
95+
# 保存为 ICO 文件
96+
images[0].save(str(output_path), format='ICO', sizes=[(s, s) for s in sizes])
97+
print(f"✓ 已生成 ICO 图标: {output_path}")
98+
return True
99+
except ImportError:
100+
# 如果没有 PIL,保存为 PNG
101+
print("警告: 未安装 Pillow,将生成 PNG 文件")
102+
print("安装 Pillow: pip install Pillow")
103+
png_path = output_path.with_suffix('.png')
104+
largest_pixmap = create_matrix_icon_pixmap(256)
105+
largest_pixmap.save(str(png_path), 'PNG')
106+
print(f"已生成 PNG 图标: {png_path}")
107+
print("提示: 可以使用在线工具将 PNG 转换为 ICO 文件")
108+
return False
109+
except Exception as e:
110+
print(f"保存图标失败: {e}")
111+
return False
112+
113+
114+
def create_icns_file(output_path):
115+
"""创建 macOS .icns 文件"""
116+
try:
117+
# macOS 可以使用 PNG,PyInstaller 会自动处理
118+
# 或者生成 iconset 然后使用 iconutil
119+
png_path = output_path.with_suffix('.png')
120+
121+
# 生成高分辨率 PNG(1024x1024)
122+
largest_pixmap = create_matrix_icon_pixmap(1024)
123+
largest_pixmap.save(str(png_path), 'PNG')
124+
print(f"✓ 已生成 PNG 图标: {png_path}")
125+
print("提示: PyInstaller 可以使用 PNG 图标,或使用 iconutil 转换为 .icns")
126+
127+
# 尝试使用 iconutil 生成 .icns(如果可用)
128+
import subprocess
129+
import shutil
130+
131+
if shutil.which('iconutil'):
132+
iconset_dir = output_path.parent / 'app_icon.iconset'
133+
iconset_dir.mkdir(exist_ok=True)
134+
135+
# 生成不同尺寸的图标
136+
sizes = {
137+
'icon_16x16.png': 16,
138+
'icon_16x16@2x.png': 32,
139+
'icon_32x32.png': 32,
140+
'icon_32x32@2x.png': 64,
141+
'icon_128x128.png': 128,
142+
'icon_128x128@2x.png': 256,
143+
'icon_256x256.png': 256,
144+
'icon_256x256@2x.png': 512,
145+
'icon_512x512.png': 512,
146+
'icon_512x512@2x.png': 1024,
147+
}
148+
149+
for filename, size in sizes.items():
150+
pixmap = create_matrix_icon_pixmap(size)
151+
pixmap.save(str(iconset_dir / filename), 'PNG')
152+
153+
# 使用 iconutil 转换为 .icns
154+
try:
155+
subprocess.run(['iconutil', '-c', 'icns', str(iconset_dir), '-o', str(output_path)],
156+
check=True, capture_output=True)
157+
print(f"✓ 已生成 ICNS 图标: {output_path}")
158+
# 清理临时目录
159+
import shutil
160+
shutil.rmtree(iconset_dir, ignore_errors=True)
161+
return True
162+
except subprocess.CalledProcessError:
163+
print("iconutil 转换失败,使用 PNG 图标")
164+
return False
165+
else:
166+
return False
167+
except Exception as e:
168+
print(f"生成图标失败: {e}")
169+
return False
170+
171+
172+
def main():
173+
"""主函数"""
174+
# 创建 QApplication(必需)
175+
app = QApplication(sys.argv)
176+
177+
script_dir = Path(__file__).parent
178+
179+
if sys.platform == 'win32':
180+
# Windows: 生成 .ico 文件
181+
ico_path = script_dir / 'app_icon.ico'
182+
print("正在生成 Windows 图标...")
183+
create_ico_file(ico_path)
184+
elif sys.platform == 'darwin':
185+
# macOS: 生成 .icns 文件
186+
icns_path = script_dir / 'app_icon.icns'
187+
print("正在生成 macOS 图标...")
188+
create_icns_file(icns_path)
189+
else:
190+
# Linux: 生成 PNG 文件
191+
png_path = script_dir / 'app_icon.png'
192+
print("正在生成 Linux 图标...")
193+
pixmap = create_matrix_icon_pixmap(256)
194+
pixmap.save(str(png_path), 'PNG')
195+
print(f"已生成 PNG 图标: {png_path}")
196+
197+
198+
if __name__ == '__main__':
199+
main()
200+

0 commit comments

Comments
 (0)