feat: DMG background with larger fonts and app design system

This commit is contained in:
小鱼开发
2026-05-19 10:45:02 +08:00
parent fc92370993
commit 09aa1ca45a
2 changed files with 55 additions and 60 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 26 KiB

+55 -60
View File
@@ -1,10 +1,7 @@
#!/usr/bin/env python3
"""
生成 DMG 背景图 — 美家卡智影设计规范
====================================
画布: 660 x 400 px
风格: 与应用 UI 一致(绿色品牌色、卡片阴影、圆角)
画布: 660 x 400 px(直接渲染,无缩放)
"""
import subprocess
@@ -14,74 +11,75 @@ from PIL import Image, ImageDraw, ImageFont
# ──────────────────────────── 配置 ────────────────────────────
W, H = 660, 400
# 颜色(引用应用 CSS 变量)
BG = (249, 250, 251) # --bg-main: #f9fafb
CARD_BG = (255, 255, 255) # --bg-card: #fff
PRIMARY = (54, 178, 106) # --primary: #36b26a
TEXT_PRIMARY = (17, 24, 39) # --text-primary: #111827
TEXT_SECONDARY = (107, 114, 128) # --text-secondary: #6b7280
TEXT_TERTIARY = (156, 163, 175) # --text-tertiary: #9ca3af
BORDER = (229, 231, 235) # --border-color: #e5e7eb
SUCCESS = (16, 185, 129) # --success: #10b981
# 阴影(模拟 CSS box-shadow
def draw_card_shadow(draw, bbox, color=(0, 0, 0), alpha=0.05, blur=8):
"""绘制卡片阴影"""
x1, y1, x2, y2 = bbox
for i in range(blur, 0, -1):
a = int(alpha * 255 * (i / blur))
offset = blur - i + 2
draw.rounded_rectangle(
[x1 - offset, y1 - offset + 2, x2 + offset, y2 + offset + 4],
radius=12,
fill=(0, 0, 0, a),
)
# 颜色
BG = (249, 250, 251)
CARD_BG = (255, 255, 255)
PRIMARY = (54, 178, 106)
SECONDARY = (24, 160, 138)
TEXT_PRIMARY = (17, 24, 39)
TEXT_SECONDARY = (107, 114, 128)
TEXT_TERTIARY = (156, 163, 175)
BORDER = (229, 231, 235)
# ──────────────────────────── 字体 ────────────────────────────
def get_font(size, bold=False):
"""获取中文字体"""
result = subprocess.run(
["fc-match", "-f", "%{file}", "PingFang SC"],
capture_output=True, text=True
)
path = result.stdout.strip()
if path and Path(path).exists():
idx = 2 if bold else 0 # 常规/粗体索引
idx = 2 if bold else 0
return ImageFont.truetype(path, size, index=idx)
return ImageFont.load_default()
font_title = get_font(22, bold=True)
font_subtitle = get_font(13, bold=True)
font_body = get_font(12)
font_caption = get_font(10)
font_title = get_font(20, bold=True)
font_subtitle = get_font(16, bold=True)
font_body = get_font(13)
font_caption = get_font(11)
# ──────────────────────────── 画布 ────────────────────────────
bg = Image.new("RGBA", (W, H), (*BG, 255))
draw = ImageDraw.Draw(bg)
# ──────────────────────────── 顶部品牌区 ────────────────────────────
# 加载 Logo(绿色 M
logo = Image.open("icons/icon.png").convert("RGBA")
logo = Image.open("../public/assets/logo.png").convert("RGBA")
logo_size = 36
logo.thumbnail((logo_size, logo_size), Image.LANCZOS)
# 放置 Logo(顶部居中偏左,与文字搭配)
logo_x = (W - logo_size) // 2 - 70
logo_y = 28
logo_x = (W - logo_size) // 2 - 65
logo_y = 20
bg.paste(logo, (logo_x, logo_y), logo)
# 品牌名称(品牌绿色
draw.text((logo_x + logo_size + 10, logo_y + 6), "美家卡智影",
fill=PRIMARY, font=font_title)
# 品牌名称 — 渐变文字效果(加宽 20px 防止截断
title_text = "美家卡智影"
title_x = logo_x + logo_size + 8
title_y = logo_y + 2
tw = int(draw.textlength(title_text, font=font_title)) + 30
th = font_title.size + 8
gradient = Image.new("RGBA", (tw, th), (0, 0, 0, 0))
for y in range(th):
ratio = y / th
r = int(PRIMARY[0] * (1 - ratio) + SECONDARY[0] * ratio)
g = int(PRIMARY[1] * (1 - ratio) + SECONDARY[1] * ratio)
b = int(PRIMARY[2] * (1 - ratio) + SECONDARY[2] * ratio)
for x in range(tw):
gradient.putpixel((x, y), (r, g, b, 255))
mask = Image.new("L", (tw, th), 0)
mask_draw = ImageDraw.Draw(mask)
mask_draw.text((0, 0), title_text, fill=255, font=font_title)
gradient.putalpha(mask)
bg.paste(gradient, (title_x, title_y), gradient)
# ──────────────────────────── 中部拖拽引导 ────────────────────────────
# 拖拽箭头(从左侧指向右侧)
arrow_y = 195
arrow_y = 200
arrow_start = 220
arrow_end = 440
arrow_mid = (arrow_start + arrow_end) // 2
# 虚线箭头身
dash_len = 6
gap_len = 4
current = arrow_start
@@ -91,22 +89,20 @@ while current < arrow_end - 10:
fill=PRIMARY, width=2)
current += dash_len + gap_len
# 箭头头部
draw.polygon([(arrow_end, arrow_y), (arrow_end - 8, arrow_y - 4),
(arrow_end - 8, arrow_y + 4)], fill=PRIMARY)
# 引导文字
draw.text((W // 2, arrow_y + 18), "将左侧图标拖拽到右侧 Applications 文件夹",
draw.text((W // 2, arrow_y + 14), "将左侧图标拖拽到右侧 Applications 文件夹",
fill=TEXT_SECONDARY, font=font_body, anchor="mm")
# ──────────────────────────── 底部提示卡片 ────────────────────────────
card_w = 420
card_h = 110
card_w = 600
card_h = 105
card_x = (W - card_w) // 2
card_y = 245
card_y = 242
radius = 12
# 卡片阴影(多层模拟)
# 阴影
shadow = Image.new("RGBA", (W, H), (0, 0, 0, 0))
shadow_draw = ImageDraw.Draw(shadow)
for i in range(6, 0, -1):
@@ -126,15 +122,14 @@ draw.rounded_rectangle(
radius=radius, fill=CARD_BG, outline=BORDER, width=1
)
# 左侧绿色竖条(强调色)
bar_w = 4
# 左侧绿色竖条
draw.rounded_rectangle(
[card_x, card_y + 16, card_x + bar_w, card_y + card_h - 16],
radius=bar_w // 2, fill=PRIMARY
[card_x, card_y + 14, card_x + 3, card_y + card_h - 14],
radius=1, fill=PRIMARY
)
# 提示标题(绿色)
draw.text((card_x + 20, card_y + 14), "首次安装提示",
# 提示标题
draw.text((card_x + 16, card_y + 12), "首次安装提示",
fill=PRIMARY, font=font_subtitle)
# 提示正文
@@ -143,14 +138,14 @@ tip_lines = [
"请右键点击应用图标,选择「打开」,或在系统设置中允许",
]
for i, line in enumerate(tip_lines):
draw.text((card_x + 20, card_y + 38 + i * 18), line,
draw.text((card_x + 16, card_y + 36 + i * 20), line,
fill=TEXT_SECONDARY, font=font_body)
# ──────────────────────────── 底部版本号 ────────────────────────────
draw.text((W // 2, H - 16), "v1.5.18",
draw.text((W // 2, H - 14), "v1.5.18",
fill=TEXT_TERTIARY, font=font_caption, anchor="mm")
# ──────────────────────────── 保存 ────────────────────────────
output = bg.convert("RGB")
output.save("dmg-background.png", "PNG")
print("✅ Generated: tauri-app/src-tauri/dmg-background.png (660x400)")
print("✅ Generated: dmg-background.png (660x400)")