#!/usr/bin/env python3 """ 生成 DMG 美化背景圖(640×400),對齊 Wails 控制台深色 splash 風格。 用法: python3 installer/macos/make-dmg-background.py 輸出: installer/macos/background.png (1x, 640×400) installer/macos/background@2x.png (2x, 1280×800 Retina) create-dmg 會自動挑 @2x 版本用於 Retina 螢幕。 """ from pathlib import Path from PIL import Image, ImageDraw, ImageFont OUT_DIR = Path(__file__).resolve().parent W, H = 640, 400 BG_TOP = (17, 24, 39) BG_BOTTOM = (11, 15, 25) TEXT = (229, 231, 235) MUTED = (148, 163, 184) ACCENT = (56, 189, 248) def make(scale: int, out_path: Path) -> None: w, h = W * scale, H * scale img = Image.new("RGB", (w, h), BG_TOP) px = img.load() for y in range(h): t = y / (h - 1) r = int(BG_TOP[0] + (BG_BOTTOM[0] - BG_TOP[0]) * t) g = int(BG_TOP[1] + (BG_BOTTOM[1] - BG_TOP[1]) * t) b = int(BG_TOP[2] + (BG_BOTTOM[2] - BG_TOP[2]) * t) for x in range(w): px[x, y] = (r, g, b) draw = ImageDraw.Draw(img) try: font_title = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 22 * scale) font_hint = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", 14 * scale) except OSError: font_title = ImageFont.load_default() font_hint = ImageFont.load_default() title = "Drag visionA-local to Applications" tw = draw.textlength(title, font=font_title) draw.text(((w - tw) / 2, 28 * scale), title, fill=TEXT, font=font_title) hint = "拖曳圖示到右邊的 Applications 即可安裝" hw = draw.textlength(hint, font=font_hint) draw.text(((w - hw) / 2, 60 * scale), hint, fill=MUTED, font=font_hint) # 箭頭位置:左右兩個 icon 約在 y=230,中心。icon 本身 128×128,由 create-dmg 擺。 # create-dmg 預設 app icon x=180, Applications x=460(y=200)。箭頭畫在中間 240-400 區段。 arrow_y = 200 * scale arrow_x1 = 260 * scale arrow_x2 = 380 * scale line_w = 3 * scale draw.line([(arrow_x1, arrow_y), (arrow_x2, arrow_y)], fill=ACCENT, width=line_w) # 箭頭頭 head = 12 * scale draw.polygon( [ (arrow_x2, arrow_y), (arrow_x2 - head, arrow_y - head // 2 - 2 * scale), (arrow_x2 - head, arrow_y + head // 2 + 2 * scale), ], fill=ACCENT, ) img.save(out_path, "PNG", optimize=True) print(f"wrote {out_path} ({out_path.stat().st_size // 1024} KB)") def main() -> None: make(1, OUT_DIR / "background.png") make(2, OUT_DIR / "background@2x.png") if __name__ == "__main__": main()