Files
SoundGame/web/space/gen_cover.py
T

89 lines
3.1 KiB
Python

"""盲航 cover.png 生成:1080x1920,深空底 + 星点 + 游戏名 + 玩法提示。"""
import math
import random
from PIL import Image, ImageDraw, ImageFilter, ImageFont
W, H = 1080, 1920
FONT = "/home/xsl/SoundGame/app/src/reflex/gen/NotoSansSC-Bold.ttf"
OUT = "/home/xsl/SoundGame/web/space/cover.png"
random.seed(42)
img = Image.new("RGB", (W, H))
px = img.load()
# 深空竖向渐变:上 #05060e -> 下 #101a33
top, bottom = (5, 6, 14), (16, 26, 51)
for y in range(H):
t = y / (H - 1)
for x in range(W):
px[x, y] = tuple(int(a + (b - a) * t) for a, b in zip(top, bottom))
d = ImageDraw.Draw(img)
# 星点
for _ in range(420):
x, y = random.randint(0, W - 1), random.randint(0, H - 1)
r = random.random()
c = random.randint(120, 255)
if r < 0.85:
d.point((x, y), fill=(c, c, min(255, c + 20)))
else:
rr = random.randint(1, 2)
d.ellipse([x - rr, y - rr, x + rr, y + rr], fill=(c, c, 255))
# 几颗亮星带光晕
glow = Image.new("RGB", (W, H), (0, 0, 0))
gd = ImageDraw.Draw(glow)
for _ in range(14):
x, y = random.randint(0, W - 1), random.randint(0, H - 1)
gd.ellipse([x - 4, y - 4, x + 4, y + 4], fill=(180, 200, 255))
glow = glow.filter(ImageFilter.GaussianBlur(6))
img = Image.blend(img, Image.new("RGB", (W, H)), 0) # no-op 保引用
from PIL import ImageChops
img = ImageChops.add(img, glow)
d = ImageDraw.Draw(img)
# 下方舷窗弧光(飞船视角的地平线辉光)
arc = Image.new("RGB", (W, H), (0, 0, 0))
ad = ImageDraw.Draw(arc)
ad.ellipse([-W * 0.55, H * 0.78, W * 1.55, H * 1.75], outline=(70, 130, 220), width=10)
arc = arc.filter(ImageFilter.GaussianBlur(18))
img = ImageChops.add(img, arc)
d = ImageDraw.Draw(img)
def text_center(y, s, size, fill, spacing=0):
f = ImageFont.truetype(FONT, size)
bbox = d.textbbox((0, 0), s, font=f)
w = bbox[2] - bbox[0]
x = (W - w) / 2 - bbox[0]
if spacing:
# 逐字画以加字距
cx = x
for ch in s:
d.text((cx, y), ch, font=f, fill=fill)
cb = d.textbbox((0, 0), ch, font=f)
cx += (cb[2] - cb[0]) + spacing
else:
d.text((x, y), s, font=f, fill=fill)
# 标题(大字,加字距)
title = "盲 航"
f = ImageFont.truetype(FONT, 300)
bbox = d.textbbox((0, 0), title, font=f)
d.text(((W - (bbox[2] - bbox[0])) / 2 - bbox[0], 640), title, font=f, fill=(232, 240, 255))
# 标题辉光
tglow = Image.new("RGB", (W, H), (0, 0, 0))
td = ImageDraw.Draw(tglow)
td.text(((W - (bbox[2] - bbox[0])) / 2 - bbox[0], 640), title, font=f, fill=(60, 90, 160))
tglow = tglow.filter(ImageFilter.GaussianBlur(24))
img = ImageChops.add(img, tglow)
d = ImageDraw.Draw(img)
d.text(((W - (bbox[2] - bbox[0])) / 2 - bbox[0], 640), title, font=f, fill=(232, 240, 255))
text_center(1060, "SPACE · BLIND FLIGHT", 40, (110, 140, 200))
text_center(1230, "闭眼驾驶,听声闪避", 64, (200, 214, 240))
text_center(1340, "警报来自哪个方向,就朝反方向滑动", 40, (130, 145, 175))
text_center(1420, "单击加速 · 双击护盾 · 撞击三次坠毁", 40, (130, 145, 175))
img.save(OUT)
print("saved", OUT, img.size)