#!/usr/bin/env python3 # -*- coding: utf-8 -*- """《星环舰长》封面生成:1080x1920 竖图(星环 + 四象限方位刻度的深空舰桥意象)。 用法:.venv-tts/bin/python tools/gen_bridge_cover.py → web/bridge/cover.png """ import math import os import numpy as np from PIL import Image, ImageDraw ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) W, H = 1080, 1920 rng = np.random.default_rng(22) # 深空径向底 yy, xx = np.mgrid[0:H, 0:W].astype(np.float32) cx, cy = W / 2, H * 0.42 d = np.sqrt((xx - cx) ** 2 + (yy - cy) ** 2) / (W * 1.1) base = np.stack([ 8 + 14 * np.exp(-d * 2.2), # R 10 + 18 * np.exp(-d * 2.0), # G 22 + 38 * np.exp(-d * 1.8), # B ], axis=2) img = Image.fromarray(np.clip(base, 0, 255).astype(np.uint8), "RGB") dr = ImageDraw.Draw(img) # 星点 for _ in range(420): x, y = rng.integers(0, W), rng.integers(0, H) b = int(rng.integers(60, 220)) r = 1 if rng.random() < 0.9 else 2 dr.ellipse([x - r, y - r, x + r, y + r], fill=(b, b, min(255, b + 20))) # 星环(倾斜椭圆弧,亮青) def ring(radius, width, alpha, tilt=0.32, span=(0, 360), color=(120, 210, 255)): bbox = [cx - radius, cy - radius * (1 - tilt), cx + radius, cy + radius * (1 + tilt)] dr.arc(bbox, span[0], span[1], fill=color, width=width) for rad, wd, col in ((430, 5, (90, 180, 230)), (455, 3, (140, 220, 255)), (480, 2, (80, 150, 210))): ring(rad, wd, 255, color=col) # 四象限刻度(左舷/右舷/舰首/舰尾 方位标记点) for ang, lab in ((180, None), (0, None), (270, None), (90, None)): a = math.radians(ang) px = cx + 500 * math.cos(a) py = cy + 500 * (1 - 0.32) * math.sin(a) dr.ellipse([px - 6, py - 6, px + 6, py + 6], fill=(255, 210, 120)) # 舰桥光晕(中心暖核) for rad, col in ((60, (255, 220, 160)), (36, (255, 235, 190)), (18, (255, 245, 220))): dr.ellipse([cx - rad, cy - rad, cx + rad, cy + rad], fill=col) img.save(os.path.join(ROOT, "web", "bridge", "cover.png")) print("cover ->", os.path.join(ROOT, "web", "bridge", "cover.png"))