rom PIL import Image, ImageDraw, ImageFont, ImageOps, ImageFilter
from pathlib import Path
SOURCE = Path('/home/ubuntu/upload/promo-regalos-prestashop.webp')
EDITED_BAG = Path('/home/ubuntu/bolsaherramientas-sin-rojo.png')
OUTPUT = Path('/home/ubuntu/promo-regalos-400x600-vertical.gif')
W, H = 400, 600
source = Image.open(SOURCE).convert('RGB')
edited_bag = Image.open(EDITED_BAG).convert('RGB')
items = [
((28, 506), '200 € — 300 €', 'LINTERNA LED', (402, 755)),
((514, 1019), '300 € — 400 €', 'CARRACA 7 EN 1', (402, 755)),
((1027, 1522), '400 € — 500 €', 'MOSQUETÓN MULTIUSOS', (402, 755)),
((1532, 2018), 'MÁS DE 500 €', 'BOLSA DE HERRAMIENTAS', (402, 755)),
]
regular = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'
bold = '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf'
def F(path, size): return ImageFont.truetype(path, size)
def centered(draw, text, xy, font, fill): draw.text(xy, text, font=font, fill=fill, anchor='mm')
def glow_panel(base, box, color=(0, 145, 255), blur=22):
glow = Image.new('RGBA', base.size, (0,0,0,0))
gd = ImageDraw.Draw(glow)
x1,y1,x2,y2 = box
gd.rounded_rectangle((x1-8,y1-8,x2+8,y2+8), radius=20, outline=(*color,210), width=8)
glow = glow.filter(ImageFilter.GaussianBlur(blur))
base.alpha_composite(glow)
frames=[]
for (x1,x2), purchase, label, (y1,y2) in items:
canvas = Image.new('RGBA', (W,H), (4,18,42,255))
# Azul marino vertical con sutil brillo radial.
light = Image.new('RGBA',(W,H),(0,0,0,0))
ld = ImageDraw.Draw(light)
ld.ellipse((-130, 45, 300, 450), fill=(0,104,220,90))
ld.ellipse((180, 230, 530, 720), fill=(0,74,180,80))
light = light.filter(ImageFilter.GaussianBlur(55))
canvas.alpha_composite(light)
d = ImageDraw.Draw(canvas)
d.rectangle((0,0,W,8), fill='#e51e2a')
d.rectangle((0,8,W,94), fill='#0755bd')
centered(d, 'REGALO POR TU COMPRA', (W//2, 37), F(bold, 20), '#ffffff')
centered(d, purchase, (W//2, 70), F(bold, 23), '#ffffff')
panel=(18,110,W-18,478)
glow_panel(canvas, panel)
d = ImageDraw.Draw(canvas)
d.rounded_rectangle(panel, radius=18, fill='#ffffff', outline='#8bc5ff', width=2)
if label == 'BOLSA DE HERRAMIENTAS':
product = edited_bag
else:
product = source.crop((x1,y1,x2,y2))
product = ImageOps.contain(product, (W-48, 335), method=Image.Resampling.LANCZOS)
canvas.alpha_composite(product.convert('RGBA'), ((W-product.width)//2, 124))
# Etiqueta inferior corta y legible.
d = ImageDraw.Draw(canvas)
d.rounded_rectangle((32, 503, W-32, 558), radius=28, fill='#e51e2a')
centered(d, label, (W//2, 531), F(bold, 19 if len(label)<19 else 15), '#ffffff')
# Pie de campaña discreto.
centered(d, 'PROMOCIÓN ESPECIAL', (W//2, 581), F(bold, 12), '#b8d9ff')
frames.append(canvas.convert('RGB'))
frames[0].save(OUTPUT, save_all=True, append_images=frames[1:], duration=[1250]*4, loop=0, optimize=True)
print(OUTPUT)
print(f'{OUTPUT.stat().st_size} bytes')