29154bd651
Co-authored-by: Copilot <copilot@github.com>
241 lines
8.7 KiB
Python
241 lines
8.7 KiB
Python
"""
|
|
Create visual test images for the Canvas API layered system.
|
|
Demonstrates base layer, door layer (with colors), hardware layer, and foreground layer.
|
|
"""
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
import os
|
|
|
|
# Canvas dimensions - all layers use the same size
|
|
CANVAS_WIDTH = 800
|
|
CANVAS_HEIGHT = 600
|
|
|
|
# Output directory
|
|
OUTPUT_DIR = os.path.join(os.path.dirname(__file__), 'static', 'images')
|
|
|
|
def create_base_layer():
|
|
"""Create base layer - a simple house background"""
|
|
img = Image.new('RGB', (CANVAS_WIDTH, CANVAS_HEIGHT), color='#87CEEB') # Sky blue
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Draw grass at bottom
|
|
draw.rectangle([(0, 450), (CANVAS_WIDTH, CANVAS_HEIGHT)], fill='#90EE90') # Light green
|
|
|
|
# Draw house body (tan/beige)
|
|
house_left = 150
|
|
house_right = 650
|
|
house_top = 200
|
|
house_bottom = 500
|
|
draw.rectangle([(house_left, house_top), (house_right, house_bottom)], fill='#D2B48C') # Tan
|
|
|
|
# Draw roof (dark brown triangle)
|
|
roof_points = [
|
|
(400, 100), # Top point
|
|
(house_left - 30, house_top), # Left bottom
|
|
(house_right + 30, house_top) # Right bottom
|
|
]
|
|
draw.polygon(roof_points, fill='#654321') # Dark brown
|
|
|
|
# Draw window openings (lighter rectangles where door/window will go)
|
|
# Door opening in center
|
|
door_left = 325
|
|
door_right = 475
|
|
door_top = 280
|
|
door_bottom = 480
|
|
draw.rectangle([(door_left, door_top), (door_right, door_bottom)], fill='#C9B896') # Lighter tan
|
|
|
|
# Add some house details (window on left side)
|
|
draw.rectangle([(200, 280), (280, 360)], fill='#87CEEB') # Window
|
|
draw.rectangle([(238, 280), (242, 360)], fill='#654321') # Window divider vertical
|
|
draw.rectangle([(200, 318), (280, 322)], fill='#654321') # Window divider horizontal
|
|
|
|
# Window on right side
|
|
draw.rectangle([(520, 280), (600, 360)], fill='#87CEEB') # Window
|
|
draw.rectangle([(558, 280), (562, 360)], fill='#654321') # Window divider vertical
|
|
draw.rectangle([(520, 318), (600, 322)], fill='#654321') # Window divider horizontal
|
|
|
|
return img
|
|
|
|
def create_door_layer(color_name, color_hex):
|
|
"""Create door layer with transparency - colored rectangle positioned in door opening"""
|
|
img = Image.new('RGBA', (CANVAS_WIDTH, CANVAS_HEIGHT), color=(0, 0, 0, 0)) # Transparent
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Door dimensions - positioned where the door opening is on the house
|
|
door_left = 330
|
|
door_right = 470
|
|
door_top = 285
|
|
door_bottom = 475
|
|
|
|
# Draw door
|
|
draw.rectangle([(door_left, door_top), (door_right, door_bottom)], fill=color_hex)
|
|
|
|
# Draw door panels (decorative)
|
|
panel_margin = 15
|
|
panel_gap = 10
|
|
|
|
# Top panel
|
|
draw.rectangle([
|
|
(door_left + panel_margin, door_top + panel_margin),
|
|
(door_right - panel_margin, door_top + panel_margin + 80)
|
|
], outline='#000000', width=3)
|
|
|
|
# Bottom panel
|
|
draw.rectangle([
|
|
(door_left + panel_margin, door_top + panel_margin + 80 + panel_gap),
|
|
(door_right - panel_margin, door_bottom - panel_margin)
|
|
], outline='#000000', width=3)
|
|
|
|
# Door handle position marker (small circle to show where handle will go)
|
|
# On the right side for left-hinge door
|
|
handle_x = door_right - 40
|
|
handle_y = door_top + (door_bottom - door_top) // 2
|
|
draw.ellipse([
|
|
(handle_x - 8, handle_y - 8),
|
|
(handle_x + 8, handle_y + 8)
|
|
], fill='#000000')
|
|
|
|
return img
|
|
|
|
def create_hardware_layer():
|
|
"""Create hardware layer with transparency - gold circle for door handle"""
|
|
img = Image.new('RGBA', (CANVAS_WIDTH, CANVAS_HEIGHT), color=(0, 0, 0, 0)) # Transparent
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Door handle position - matches the marker on the door
|
|
# Right side for left-hinge door
|
|
handle_x = 430 # door_right (470) - 40
|
|
handle_y = 380 # middle of door
|
|
|
|
# Draw decorative backplate (bronze/gold rectangle)
|
|
plate_width = 30
|
|
plate_height = 80
|
|
draw.rectangle([
|
|
(handle_x - plate_width//2, handle_y - plate_height//2),
|
|
(handle_x + plate_width//2, handle_y + plate_height//2)
|
|
], fill='#B8860B') # Dark goldenrod
|
|
|
|
# Draw handle (gold circle)
|
|
handle_radius = 20
|
|
draw.ellipse([
|
|
(handle_x - handle_radius, handle_y - handle_radius),
|
|
(handle_x + handle_radius, handle_y + handle_radius)
|
|
], fill='#FFD700') # Gold
|
|
|
|
# Add shine/highlight
|
|
highlight_offset = 6
|
|
draw.ellipse([
|
|
(handle_x - highlight_offset, handle_y - highlight_offset),
|
|
(handle_x - highlight_offset + 8, handle_y - highlight_offset + 8)
|
|
], fill='#FFFFE0') # Light yellow highlight
|
|
|
|
return img
|
|
|
|
def create_foreground_layer():
|
|
"""Create foreground layer with transparency - plants at bottom"""
|
|
img = Image.new('RGBA', (CANVAS_WIDTH, CANVAS_HEIGHT), color=(0, 0, 0, 0)) # Transparent
|
|
draw = ImageDraw.Draw(img)
|
|
|
|
# Draw plants/bushes at the bottom corners
|
|
# Left plant
|
|
left_plant_x = 120
|
|
plant_y = 480
|
|
for i in range(3):
|
|
offset_x = i * 25
|
|
offset_y = i * 10
|
|
# Draw leaves (green circles)
|
|
draw.ellipse([
|
|
(left_plant_x + offset_x - 30, plant_y + offset_y - 30),
|
|
(left_plant_x + offset_x + 30, plant_y + offset_y + 30)
|
|
], fill='#228B22') # Forest green
|
|
|
|
# Right plant
|
|
right_plant_x = 680
|
|
for i in range(3):
|
|
offset_x = -i * 25
|
|
offset_y = i * 10
|
|
# Draw leaves (green circles)
|
|
draw.ellipse([
|
|
(right_plant_x + offset_x - 30, plant_y + offset_y - 30),
|
|
(right_plant_x + offset_x + 30, plant_y + offset_y + 30)
|
|
], fill='#228B22') # Forest green
|
|
|
|
# Add some decorative flowers
|
|
flower_positions = [
|
|
(100, 520), (140, 510), (160, 530), # Left side
|
|
(640, 530), (660, 510), (700, 520) # Right side
|
|
]
|
|
|
|
for fx, fy in flower_positions:
|
|
# Flower petals (pink circles)
|
|
petal_radius = 8
|
|
for angle in range(0, 360, 72): # 5 petals
|
|
import math
|
|
px = fx + int(12 * math.cos(math.radians(angle)))
|
|
py = fy + int(12 * math.sin(math.radians(angle)))
|
|
draw.ellipse([
|
|
(px - petal_radius, py - petal_radius),
|
|
(px + petal_radius, py + petal_radius)
|
|
], fill='#FFB6C1') # Light pink
|
|
|
|
# Flower center (yellow circle)
|
|
center_radius = 6
|
|
draw.ellipse([
|
|
(fx - center_radius, fy - center_radius),
|
|
(fx + center_radius, fy + center_radius)
|
|
], fill='#FFD700') # Gold
|
|
|
|
return img
|
|
|
|
def main():
|
|
print("Creating visual test images for Canvas API...")
|
|
|
|
# Define paths
|
|
base_path = os.path.join(OUTPUT_DIR, 'window', 'storm-window', '404')
|
|
layers_path = os.path.join(OUTPUT_DIR, 'window', 'storm-window', 'layers')
|
|
|
|
# Create directories
|
|
os.makedirs(base_path, exist_ok=True)
|
|
os.makedirs(layers_path, exist_ok=True)
|
|
|
|
# Create base layer
|
|
print("Creating base layer (house)...")
|
|
base_img = create_base_layer()
|
|
base_img.save(os.path.join(layers_path, 'base.jpg'), quality=90)
|
|
print(f" ✓ Saved: {layers_path}/base.jpg")
|
|
|
|
# Create door layers in various colors
|
|
door_colors = {
|
|
'white': '#FFFFFF',
|
|
'black': '#2C2C2C',
|
|
'bronze': '#8B6914',
|
|
'tan': '#D2B48C'
|
|
}
|
|
|
|
print("\nCreating door layers...")
|
|
for color_name, color_hex in door_colors.items():
|
|
door_img = create_door_layer(color_name, color_hex)
|
|
door_img.save(os.path.join(base_path, f'door-{color_name}.png'))
|
|
print(f" ✓ Saved: {base_path}/door-{color_name}.png")
|
|
|
|
# Create hardware layer
|
|
print("\nCreating hardware layer (gold handle)...")
|
|
hardware_img = create_hardware_layer()
|
|
hardware_img.save(os.path.join(layers_path, 'hardware.png'))
|
|
print(f" ✓ Saved: {layers_path}/hardware.png")
|
|
|
|
# Create foreground layer
|
|
print("\nCreating foreground layer (plants)...")
|
|
foreground_img = create_foreground_layer()
|
|
foreground_img.save(os.path.join(layers_path, 'foreground.png'))
|
|
print(f" ✓ Saved: {layers_path}/foreground.png")
|
|
|
|
print("\n✅ All images created successfully!")
|
|
print("\nTest URLs:")
|
|
print(" Left-hinge: http://localhost:8080/quiz/product/404")
|
|
print(" Right-hinge: http://localhost:8080/quiz/product/404R")
|
|
print("\nThe right-hinge version will flip the door and hardware layers horizontally.")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|