"""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")