Files
python-maze/generate_images.py

322 lines
10 KiB
Python

"""Generate required images for SEO and branding."""
from PIL import Image, ImageDraw, ImageFont
import os
# Create images directory
os.makedirs('web/static/images', exist_ok=True)
# Neo-Brutalism color palette
COLORS = {
'yellow': '#FFE500',
'pink': '#FF10F0',
'cyan': '#00F0FF',
'green': '#39FF14',
'black': '#000000',
'white': '#FFFFFF',
'gray': '#F5F5F5'
}
def create_favicon(size, filename):
"""Create a favicon with Neo-Brutalism design."""
img = Image.new('RGB', (size, size), COLORS['yellow'])
draw = ImageDraw.Draw(img)
# Draw thick border
border_width = max(2, size // 8)
draw.rectangle([0, 0, size-1, size-1], outline=COLORS['black'], width=border_width)
# Draw maze-like pattern
cell_size = size // 4
for i in range(1, 4):
# Vertical lines
x = i * cell_size
draw.line([(x, border_width), (x, size - border_width)],
fill=COLORS['black'], width=max(1, size // 16))
# Horizontal lines
y = i * cell_size
draw.line([(border_width, y), (size - border_width, y)],
fill=COLORS['black'], width=max(1, size // 16))
img.save(f'web/static/images/{filename}')
print(f"Created {filename} ({size}x{size})")
def create_twitter_image():
"""Create Twitter card image (1200x675)."""
width, height = 1200, 675
img = Image.new('RGB', (width, height), COLORS['gray'])
draw = ImageDraw.Draw(img)
# Background with gradient effect (using rectangles)
for i in range(0, height, 20):
color_mix = int(245 - (i / height) * 20)
draw.rectangle([0, i, width, i+20],
fill=f'#{color_mix:02x}{color_mix:02x}{color_mix:02x}')
# Title box
title_height = 150
title_y = 50
draw.rectangle([50, title_y, width-50, title_y + title_height],
fill=COLORS['yellow'])
draw.rectangle([50, title_y, width-50, title_y + title_height],
outline=COLORS['black'], width=8)
# Shadow for title box
shadow_offset = 12
draw.rectangle([50 + shadow_offset, title_y + shadow_offset,
width-50 + shadow_offset, title_y + title_height + shadow_offset],
outline=COLORS['black'], width=8)
# Try to use a bold font, fallback to default
try:
font_large = ImageFont.truetype("arial.ttf", 70)
font_medium = ImageFont.truetype("arial.ttf", 50)
font_small = ImageFont.truetype("arial.ttf", 35)
except:
font_large = ImageFont.load_default()
font_medium = ImageFont.load_default()
font_small = ImageFont.load_default()
# Title text
title = "MAZE GENERATOR"
bbox = draw.textbbox((0, 0), title, font=font_large)
text_width = bbox[2] - bbox[0]
text_x = (width - text_width) // 2
draw.text((text_x, title_y + 40), title, fill=COLORS['black'], font=font_large)
# Features boxes
features = [
"8 ALGORITHMS",
"ANIMATED SOLVING",
"NEO-BRUTALISM"
]
feature_y = title_y + title_height + 60
box_width = 320
box_height = 100
spacing = 40
total_width = len(features) * box_width + (len(features) - 1) * spacing
start_x = (width - total_width) // 2
colors_cycle = [COLORS['pink'], COLORS['cyan'], COLORS['green']]
for i, feature in enumerate(features):
x = start_x + i * (box_width + spacing)
# Shadow
draw.rectangle([x + 8, feature_y + 8, x + box_width + 8, feature_y + box_height + 8],
fill=COLORS['black'])
# Box
draw.rectangle([x, feature_y, x + box_width, feature_y + box_height],
fill=colors_cycle[i])
draw.rectangle([x, feature_y, x + box_width, feature_y + box_height],
outline=COLORS['black'], width=6)
# Text
bbox = draw.textbbox((0, 0), feature, font=font_small)
text_w = bbox[2] - bbox[0]
text_h = bbox[3] - bbox[1]
draw.text((x + (box_width - text_w) // 2,
feature_y + (box_height - text_h) // 2),
feature, fill=COLORS['black'], font=font_small)
img.save('web/static/images/twitter-image.png')
print("Created twitter-image.png (1200x675)")
def create_og_image():
"""Create Open Graph image (1200x630)."""
width, height = 1200, 630
img = Image.new('RGB', (width, height), COLORS['yellow'])
draw = ImageDraw.Draw(img)
# Border
draw.rectangle([0, 0, width-1, height-1], outline=COLORS['black'], width=10)
# Try to use a bold font, fallback to default
try:
font_title = ImageFont.truetype("arial.ttf", 90)
font_subtitle = ImageFont.truetype("arial.ttf", 45)
except:
font_title = ImageFont.load_default()
font_subtitle = ImageFont.load_default()
# Title
title = "MAZE GENERATOR"
bbox = draw.textbbox((0, 0), title, font=font_title)
text_width = bbox[2] - bbox[0]
draw.text(((width - text_width) // 2, 150), title,
fill=COLORS['black'], font=font_title)
# Subtitle
subtitle = "8 ALGORITHMS • ANIMATED SOLVING"
bbox = draw.textbbox((0, 0), subtitle, font=font_subtitle)
text_width = bbox[2] - bbox[0]
draw.text(((width - text_width) // 2, 280), subtitle,
fill=COLORS['black'], font=font_subtitle)
# Draw simple maze pattern
maze_size = 300
maze_x = (width - maze_size) // 2
maze_y = 380
cell_size = maze_size // 6
# Background for maze
draw.rectangle([maze_x - 10, maze_y - 10,
maze_x + maze_size + 10, maze_y + maze_size + 10],
fill=COLORS['white'])
draw.rectangle([maze_x - 10, maze_y - 10,
maze_x + maze_size + 10, maze_y + maze_size + 10],
outline=COLORS['black'], width=6)
# Draw grid
for i in range(7):
# Vertical
x = maze_x + i * cell_size
draw.line([(x, maze_y), (x, maze_y + maze_size)],
fill=COLORS['black'], width=3)
# Horizontal
y = maze_y + i * cell_size
draw.line([(maze_x, y), (maze_x + maze_size, y)],
fill=COLORS['black'], width=3)
img.save('web/static/images/og-image.png')
print("Created og-image.png (1200x630)")
def create_apple_touch_icon():
"""Create Apple touch icon (180x180)."""
size = 180
img = Image.new('RGB', (size, size), COLORS['yellow'])
draw = ImageDraw.Draw(img)
# Border
border = 8
draw.rectangle([0, 0, size-1, size-1], outline=COLORS['black'], width=border)
# Simple maze M letter
try:
font = ImageFont.truetype("arial.ttf", 120)
except:
font = ImageFont.load_default()
text = "M"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
draw.text(((size - text_width) // 2, (size - text_height) // 2 - 10),
text, fill=COLORS['black'], font=font)
img.save('web/static/images/apple-touch-icon.png')
print("Created apple-touch-icon.png (180x180)")
def create_pwa_icons():
"""Create PWA icons."""
for size in [192, 512]:
img = Image.new('RGB', (size, size), COLORS['yellow'])
draw = ImageDraw.Draw(img)
# Border
border = max(8, size // 24)
draw.rectangle([0, 0, size-1, size-1], outline=COLORS['black'], width=border)
# Draw maze pattern
cell_size = size // 8
padding = border * 2
for i in range(1, 8):
x = padding + i * cell_size
y = padding + i * cell_size
# Some vertical lines
if i % 2 == 0:
draw.line([(x, padding), (x, size - padding)],
fill=COLORS['black'], width=max(2, size // 64))
# Some horizontal lines
if i % 3 == 1:
draw.line([(padding, y), (size - padding, y)],
fill=COLORS['black'], width=max(2, size // 64))
filename = f'icon-{size}x{size}.png'
img.save(f'web/static/images/{filename}')
print(f"Created {filename} ({size}x{size})")
def create_screenshot():
"""Create a generic screenshot placeholder."""
width, height = 1280, 720
img = Image.new('RGB', (width, height), COLORS['gray'])
draw = ImageDraw.Draw(img)
# Header
header_height = 120
draw.rectangle([0, 0, width, header_height], fill=COLORS['yellow'])
draw.rectangle([0, 0, width, header_height], outline=COLORS['black'], width=8)
try:
font = ImageFont.truetype("arial.ttf", 60)
except:
font = ImageFont.load_default()
text = "MAZE GENERATOR - SCREENSHOT"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
draw.text(((width - text_width) // 2, 30), text, fill=COLORS['black'], font=font)
# Draw sample maze area
maze_area_x = 50
maze_area_y = header_height + 50
maze_area_w = 600
maze_area_h = 500
draw.rectangle([maze_area_x, maze_area_y,
maze_area_x + maze_area_w, maze_area_y + maze_area_h],
fill=COLORS['white'])
draw.rectangle([maze_area_x, maze_area_y,
maze_area_x + maze_area_w, maze_area_y + maze_area_h],
outline=COLORS['black'], width=6)
# Controls panel
panel_x = maze_area_x + maze_area_w + 50
panel_y = maze_area_y
panel_w = width - panel_x - 50
panel_h = maze_area_h
draw.rectangle([panel_x, panel_y, panel_x + panel_w, panel_y + panel_h],
fill=COLORS['cyan'])
draw.rectangle([panel_x, panel_y, panel_x + panel_w, panel_y + panel_h],
outline=COLORS['black'], width=6)
img.save('web/static/images/screenshot.png')
print("Created screenshot.png (1280x720)")
# Generate all images
print("Generating images...")
print("-" * 50)
# Favicons
create_favicon(16, 'favicon-16x16.png')
create_favicon(32, 'favicon-32x32.png')
# Social media
create_twitter_image()
create_og_image()
# Mobile
create_apple_touch_icon()
create_pwa_icons()
# Screenshot
create_screenshot()
print("-" * 50)
print("All images generated successfully!")
print("\nGenerated files:")
print(" web/static/images/favicon-16x16.png")
print(" web/static/images/favicon-32x32.png")
print(" web/static/images/apple-touch-icon.png")
print(" web/static/images/icon-192x192.png")
print(" web/static/images/icon-512x512.png")
print(" web/static/images/twitter-image.png")
print(" web/static/images/og-image.png")
print(" web/static/images/screenshot.png")