"""Gera icicle.png (59x222), o sprite do projetil de gelo do Blutfest no lugar do original (proofmart, sem licenca clara). Desenho proprio do FredyGames, dedicado ao dominio publico (CC0 1.0). Uso: python make_icicle.py icicle.png (precisa do Pillow).""" import sys from PIL import Image, ImageDraw S = 4 W, H = 59, 222 w, h = W * S, H * S # Silhueta: larga no alto, afinando ate a ponta de baixo, com uma leve curva. left, right = [], [] for i in range(0, 101): t = i / 100 y = 6 + t * (H - 12) half = (24 * (1 - t) ** 0.85 + 1.2) * (1 + 0.06 * ((i * 7) % 5 - 2) / 2 * (1 - t)) cx = 29.5 + 3 * t - 4 * t * t left.append(((cx - half) * S, y * S)) right.append(((cx + half) * S, y * S)) poly = left + right[::-1] mask = Image.new("L", (w, h), 0) ImageDraw.Draw(mask).polygon(poly, fill=255) body = Image.new("RGBA", (w, h), (0, 0, 0, 0)) px = body.load() mp = mask.load() for y in range(h): t = y / h for x in range(w): if mp[x, y]: u = (x / w - 0.5) * 2 shade = 0.55 + 0.35 * (1 - abs(u + 0.25)) - 0.25 * t r = int(120 + 110 * shade) g = int(170 + 70 * shade) b = int(215 + 38 * shade) px[x, y] = (min(r, 255), min(g, 255), min(b, 255), 235) d = ImageDraw.Draw(body) # Brilhos d.polygon([(22 * S, 22 * S), (28 * S, 22 * S), (31 * S, 130 * S), (27 * S, 130 * S)], fill=(255, 255, 255, 190)) d.polygon([(36 * S, 34 * S), (39 * S, 34 * S), (36 * S, 95 * S), (34 * S, 95 * S)], fill=(235, 248, 255, 150)) body.putalpha(Image.eval(mask, lambda v: v).point(lambda v: v)) # Contorno edge = Image.new("RGBA", (w, h), (0, 0, 0, 0)) ImageDraw.Draw(edge).line(poly + [poly[0]], fill=(70, 110, 170, 255), width=2 * S, joint="curve") edge.putalpha(Image.composite(edge.getchannel("A"), Image.new("L", (w, h), 0), mask.point(lambda v: 255))) out = Image.alpha_composite(body, edge).resize((W, H), Image.LANCZOS) out.save(sys.argv[1], optimize=True)