Files
iHaiDeeZ--SSBU/scripts/make-art.py
T

85 lines
3.3 KiB
Python

#!/usr/bin/env python3
"""SSBU's home screen art: sce_sys/icon0.png (512x512) and sce_sys/pic1.png (1920x1080).
Drawn from shapes only (a dusk sky, a floating stage with two side platforms, "SSBU" in DejaVu Sans Bold, Bitstream
Vera licence): no game asset, character or logo.
Usage: python3 scripts/make-art.py [out dir, default sce_sys]
"""
import os
import random
import sys
from PIL import Image, ImageDraw, ImageFilter, ImageFont
FONT = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"
def lerp(a, b, t):
t = max(0.0, min(1.0, t))
return tuple(int(round(a[k] + (b[k] - a[k]) * t)) for k in range(len(a)))
def sky(w, h):
img = Image.new("RGB", (w, h))
d = ImageDraw.Draw(img)
top, mid, low = (12, 14, 40), (52, 30, 92), (232, 112, 72)
for y in range(h):
t = y / (h - 1)
d.line([(0, y), (w, y)], fill=lerp(top, mid, t / 0.6) if t < 0.6 else lerp(mid, low, (t - 0.6) / 0.4))
rnd = random.Random(3)
for _ in range(int(w * h / 4000)):
x, y = rnd.random() * w, rnd.random() * h * 0.5
r = max(1.0, min(w, h) * rnd.uniform(0.001, 0.003))
d.ellipse([x - r, y - r, x + r, y + r], fill=lerp((180, 180, 220), (255, 250, 230), rnd.random()))
return img
def stage(img, cx, y, width):
"""A floating stage seen from the side, two small platforms above it, a glow underneath."""
w, h = img.size
glow = Image.new("RGBA", (w, h), (0, 0, 0, 0))
ImageDraw.Draw(glow).ellipse([cx - width * 0.6, y - width * 0.05, cx + width * 0.6, y + width * 0.25],
fill=(255, 170, 90, 120))
img.paste(glow.filter(ImageFilter.GaussianBlur(width * 0.08)), (0, 0), glow.filter(ImageFilter.GaussianBlur(width * 0.08)))
d = ImageDraw.Draw(img)
t = width * 0.06
d.polygon([(cx - width / 2, y), (cx + width / 2, y), (cx + width * 0.32, y + width * 0.2),
(cx - width * 0.32, y + width * 0.2)], fill=(30, 22, 48))
d.rectangle([cx - width / 2, y - t * 0.35, cx + width / 2, y + t * 0.25], fill=(240, 236, 255))
for side in (-1, 1):
px = cx + side * width * 0.24
d.rounded_rectangle([px - width * 0.12, y - width * 0.22, px + width * 0.12, y - width * 0.22 + t * 0.45],
radius=t * 0.2, fill=(240, 236, 255))
def title(img, text, cx, cy, size):
font = ImageFont.truetype(FONT, size)
d = ImageDraw.Draw(img)
box = d.textbbox((0, 0), text, font=font)
x, y = cx - (box[2] - box[0]) / 2 - box[0], cy - (box[3] - box[1]) / 2 - box[1]
shadow = Image.new("RGBA", img.size, (0, 0, 0, 0))
ImageDraw.Draw(shadow).text((x, y + size * 0.05), text, font=font, fill=(0, 0, 0, 170))
shadow = shadow.filter(ImageFilter.GaussianBlur(size * 0.05))
img.paste(shadow, (0, 0), shadow)
d.text((x, y), text, font=font, fill=(255, 248, 236))
def make(w, h, title_size, stage_y, stage_w, title_y):
img = sky(w, h)
stage(img, w / 2, h * stage_y, w * stage_w)
title(img, "SSBU", w / 2, h * title_y, title_size)
return img
def main():
out = sys.argv[1] if len(sys.argv) > 1 else "sce_sys"
os.makedirs(out, exist_ok=True)
make(512, 512, 150, 0.72, 0.8, 0.33).save(os.path.join(out, "icon0.png"))
make(1920, 1080, 260, 0.74, 0.5, 0.32).save(os.path.join(out, "pic1.png"))
print("art in", out)
if __name__ == "__main__":
main()