""" Karvis 牌 MetaApp 封面生成器 风格: 黑底硬边 + 紫罗兰高亮 + 大号标题 — 跟 v0.4 整体 UI 一致 """ from PIL import Image, ImageDraw, ImageFont import os W, H = 800, 1200 # 4:6 竖版, 适合 Bot Browser 卡片 out = "/Users/kyle.he/idbots/project/bots/2/2026-10-09/metaapp_chain_ipo/cover.png" # 颜色 (v0.4 调色板) BG = (11, 14, 26) # #0B0E1A INK = (236, 238, 247) # #ECEEF7 VIOLET = (124, 92, 255) # #7C5CFF CYAN = (0, 224, 255) # #00E0FF DIM = (155, 160, 189) # #9BA0BD img = Image.new('RGB', (W, H), BG) d = ImageDraw.Draw(img) # 字体路径: 优先 Impact 类, 失败降级到系统 sans FONT_PATHS = [ '/System/Library/Fonts/Supplemental/Impact.ttf', '/Library/Fonts/Impact.ttf', '/System/Library/Fonts/Helvetica.ttc', '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', '/usr/share/fonts/TTF/DejaVuSans-Bold.ttf', ] def load(idx, sz): for p in FONT_PATHS: if os.path.exists(p): try: return ImageFont.truetype(p, sz) except Exception: pass return ImageFont.load_default() f_eyebrow = load(0, 28) f_title = load(0, 88) f_sub = load(1, 36) f_meta = load(1, 22) # 顶部 eyebrow d.text((40, 50), 'ROBOTAXI', font=f_eyebrow, fill=VIOLET) # 标题 (主) — 一行装不下就拆 d.text((40, 100), '从 1 个 bot', font=f_title, fill=INK) d.text((40, 200), '出发', font=f_title, fill=INK) # 副标题 d.text((40, 320), '到 100 个 bot', font=f_sub, fill=DIM) d.text((40, 360), '护送', font=f_sub, fill=DIM) # 中间分隔线 d.line((40, 430, 760, 430), fill=VIOLET, width=3) # 玩法要点 3 行 play_lines = [ '接 8 秒弹窗的派单', '跑 51 种路上事件', '攒 bot 司机买 bot 二手车', ] for i, line in enumerate(play_lines): d.text((40, 470 + i * 60), '· ' + line, font=f_meta, fill=INK) # 底部 — 副品牌 d.line((40, 1080, 760, 1080), fill=VIOLET, width=1) d.text((40, 1100), 'Karvis 牌 · v0.6.x · MVC', font=f_meta, fill=DIM) d.text((40, 1130), '真实记录 · 不靠假 NPC', font=f_meta, fill=DIM) img.save(out, 'PNG', optimize=True) print('OK', out, os.path.getsize(out), 'bytes')