# Gera o menuback.jpg do tema Standard do LBreakoutHD no build do fredygames.com. # # O menuback.jpg original usa a mesma foto da Unsplash da moldura (frame.png), que fica de fora (ver # removed.txt). Este fundo e montado so com material do proprio tema: back0.jpg (dominio publico, # publicdomainpictures.net, segundo o CREDITS do tema), os tijolos, a raquete e a bola do tema e o # titulo escrito com a Source Sans Pro Bold do tema (fnormal.otf, SIL OFL). Mesmo tamanho (1920x1080) # e mesma area do menu (theme.ini: centerX 270, centerY 680), entao o theme.ini nao muda. # # python make-menuback.py # # Precisa da Pillow (o build usa a 12.3.0, com FreeType 2.14.3); outra versao pode gerar outros bytes, # e o build-lbreakouthd.sh confere o resultado pelo SHA-256. import sys from pathlib import Path from PIL import Image, ImageDraw, ImageFilter, ImageFont theme = Path(sys.argv[1]) out = Path(sys.argv[2]) W, H = 1920, 1080 BW, BH = 90, 45 # tamanho dos tijolos no tema (theme.ini) back = Image.open(theme / "back0.jpg").convert("RGB").resize((W, H), Image.LANCZOS).convert("RGBA") # Faixa escura a esquerda, sob o titulo e o menu, que some aos poucos para a direita. shade = Image.new("L", (W, 1), 0) for x in range(W): if x < 560: a = 170 elif x < 860: a = 170 * (860 - x) // 300 else: a = 0 shade.putpixel((x, 0), a) shade = shade.resize((W, H)) back.alpha_composite(Image.merge("RGBA", (*Image.new("RGB", (W, H), (8, 16, 32)).split(), shade))) bricks = Image.open(theme / "bricks.png").convert("RGBA") tile = lambda i: bricks.crop((i * BW, 0, (i + 1) * BW, BH)) # Uma parede de tijolos a direita, uma cor por fileira (indices de bricks.png), com sombra. rows = [10, 11, 14, 12, 13, 15] # vermelho, laranja, amarelo, verde, azul, magenta wall = Image.new("RGBA", (W, H), (0, 0, 0, 0)) x0, y0 = 900, 250 for row, color in enumerate(rows): for col in range(10): wall.alpha_composite(tile(color), (x0 + col * BW, y0 + row * BH)) alpha = wall.getchannel("A").filter(ImageFilter.GaussianBlur(6)) shadow = Image.merge("RGBA", (*Image.new("RGB", (W, H), (0, 0, 0)).split(), alpha.point(lambda v: v * 3 // 5))) back.alpha_composite(shadow, (16, 16)) back.alpha_composite(wall) # Raquete (linha 0 de paddle.png: ponta esquerda, meio, ponta direita) e bola. paddle = Image.open(theme / "paddle.png").convert("RGBA") pw = paddle.height // 4 part = lambda i: paddle.crop((i * pw, 0, (i + 1) * pw, pw)) px, py = 1160, 900 back.alpha_composite(part(0), (px, py)) for i in range(1, 5): back.alpha_composite(part(1), (px + i * pw, py)) back.alpha_composite(part(2), (px + 5 * pw, py)) ball = Image.open(theme / "ball.png").convert("RGBA") bs = ball.height back.alpha_composite(ball.crop((0, 0, bs, bs)), (px + 3 * pw - bs // 2 + 40, py - 190)) # Titulo. font = ImageFont.truetype(str(theme / "fnormal.otf"), 150) title = Image.new("RGBA", (W, H), (0, 0, 0, 0)) draw = ImageDraw.Draw(title) draw.text((70, 40), "LBreakout", font=font, fill=(235, 240, 248, 255)) hd_x = 70 + draw.textlength("LBreakout", font=font) + 8 draw.text((hd_x, 40), "HD", font=font, fill=(255, 220, 0, 255)) talpha = title.getchannel("A").filter(ImageFilter.GaussianBlur(5)) back.alpha_composite(Image.merge("RGBA", (*Image.new("RGB", (W, H), (0, 0, 0)).split(), talpha)), (6, 8)) back.alpha_composite(title) back.convert("RGB").save(out, "JPEG", quality=90, optimize=True)