pyPhotoAlbum/examples/generate_screenshots.py
Duncan Tourolle 46585228fd
Some checks failed
Lint / lint (push) Failing after 2m46s
Tests / test (3.11) (push) Has been cancelled
Tests / test (3.9) (push) Has been cancelled
Tests / test (3.10) (push) Has been cancelled
first commit
2025-10-21 22:02:49 +02:00

428 lines
14 KiB
Python

#!/usr/bin/env python3
"""
Generate Documentation Screenshots
This script creates visual examples for documentation purposes:
- Sample layouts
- Template demonstrations
- Feature showcases
- UI mockups
Note: This creates programmatic representations rather than actual screenshots.
For real screenshots, run the application and use a screen capture tool.
"""
import os
import sys
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from pyPhotoAlbum.project import Project, Page
from pyPhotoAlbum.page_layout import PageLayout
from pyPhotoAlbum.models import ImageData, TextBoxData, PlaceholderData
from pyPhotoAlbum.project_serializer import save_to_zip
import tempfile
def create_visual_mockup(path: str, title: str, description: str, elements: list):
"""
Create a visual mockup image showing a layout
Args:
path: Output path for the image
title: Title for the mockup
description: Description text
elements: List of (type, x, y, w, h, label) tuples
"""
try:
from PIL import Image, ImageDraw, ImageFont
# Create canvas (A4 aspect ratio)
width, height = 800, 1132
img = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(img)
# Try to load a nice font
try:
title_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 32)
desc_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 18)
label_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14)
except:
title_font = ImageFont.load_default()
desc_font = ImageFont.load_default()
label_font = ImageFont.load_default()
# Draw title
draw.text((20, 20), title, fill='black', font=title_font)
# Draw description
draw.text((20, 65), description, fill='gray', font=desc_font)
# Draw page boundary
page_margin = 50
page_top = 120
page_bottom = height - 50
page_width = width - 2 * page_margin
page_height = page_bottom - page_top
# Light gray page background
draw.rectangle(
[(page_margin, page_top), (width - page_margin, page_bottom)],
fill='#f5f5f5',
outline='#cccccc',
width=2
)
# Draw elements
colors = {
'image': '#e3f2fd', # Light blue
'text': '#fff9c4', # Light yellow
'placeholder': '#e8f5e9' # Light green
}
for elem_type, x, y, w, h, label in elements:
# Convert from mm to pixels (rough approximation)
px = page_margin + (x / 210) * page_width
py = page_top + (y / 297) * page_height
pw = (w / 210) * page_width
ph = (h / 297) * page_height
# Draw element
color = colors.get(elem_type, '#eeeeee')
draw.rectangle(
[(px, py), (px + pw, py + ph)],
fill=color,
outline='#666666',
width=2
)
# Draw label
if label:
label_bbox = draw.textbbox((0, 0), label, font=label_font)
label_w = label_bbox[2] - label_bbox[0]
label_h = label_bbox[3] - label_bbox[1]
label_x = px + (pw - label_w) / 2
label_y = py + (ph - label_h) / 2
draw.text((label_x, label_y), label, fill='#333333', font=label_font)
# Save
img.save(path)
print(f" Created: {path}")
return True
except Exception as e:
print(f" Error creating mockup: {e}")
return False
def generate_layout_examples():
"""Generate example layout screenshots"""
print("\n" + "="*60)
print("Generating Layout Examples")
print("="*60)
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
# Example 1: Single large image
print("\n1. Single Large Image Layout")
create_visual_mockup(
str(output_dir / "layout_single_large.png"),
"Single Large Image Layout",
"One large image with caption",
[
('image', 10, 10, 190, 250, 'Large Image'),
('text', 10, 270, 190, 20, 'Caption Text')
]
)
# Example 2: Grid 2x2
print("\n2. Grid 2x2 Layout")
create_visual_mockup(
str(output_dir / "layout_grid_2x2.png"),
"Grid 2x2 Layout",
"Four images in a 2x2 grid",
[
('image', 10, 10, 95, 95, 'Image 1'),
('image', 105, 10, 95, 95, 'Image 2'),
('image', 10, 110, 95, 95, 'Image 3'),
('image', 105, 110, 95, 95, 'Image 4')
]
)
# Example 3: Mixed layout
print("\n3. Mixed Layout")
create_visual_mockup(
str(output_dir / "layout_mixed.png"),
"Mixed Layout",
"Combination of images and text boxes",
[
('image', 10, 10, 190, 120, 'Header Image'),
('text', 10, 140, 190, 25, 'Title'),
('image', 10, 175, 90, 90, 'Image 1'),
('image', 110, 175, 90, 90, 'Image 2'),
('text', 10, 270, 190, 15, 'Footer')
]
)
# Example 4: Template with placeholders
print("\n4. Template with Placeholders")
create_visual_mockup(
str(output_dir / "layout_template.png"),
"Template Layout",
"Page template with placeholder blocks",
[
('placeholder', 10, 10, 190, 140, 'Drop Image Here'),
('placeholder', 10, 160, 90, 90, 'Image'),
('placeholder', 110, 160, 90, 90, 'Image'),
('text', 10, 260, 190, 25, 'Text Box')
]
)
def generate_feature_examples():
"""Generate feature demonstration screenshots"""
print("\n" + "="*60)
print("Generating Feature Examples")
print("="*60)
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
# Alignment demonstration
print("\n1. Alignment Features")
create_visual_mockup(
str(output_dir / "feature_alignment.png"),
"Alignment Tools",
"Align left, center, right, and distribute",
[
('image', 10, 10, 50, 50, 'Img 1'),
('image', 70, 10, 50, 50, 'Img 2'),
('image', 130, 10, 50, 50, 'Img 3'),
('text', 10, 80, 170, 15, 'Aligned and distributed horizontally')
]
)
# Sizing demonstration
print("\n2. Sizing Features")
create_visual_mockup(
str(output_dir / "feature_sizing.png"),
"Sizing Tools",
"Make same size, width, or height",
[
('image', 10, 10, 80, 80, 'Same Size'),
('image', 100, 10, 80, 80, 'Same Size'),
('image', 10, 100, 80, 60, 'Same Width'),
('image', 100, 100, 80, 80, 'Same Width')
]
)
# Z-order demonstration
print("\n3. Z-Order (Layering)")
create_visual_mockup(
str(output_dir / "feature_zorder.png"),
"Z-Order / Layering",
"Elements can be ordered in layers",
[
('image', 30, 30, 100, 100, 'Background'),
('image', 60, 60, 100, 100, 'Middle'),
('image', 90, 90, 100, 100, 'Foreground')
]
)
def generate_workflow_example():
"""Generate a complete workflow example"""
print("\n" + "="*60)
print("Generating Workflow Example")
print("="*60)
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
# Step 1: Empty page
print("\n1. Start with empty page")
create_visual_mockup(
str(output_dir / "workflow_01_empty.png"),
"Step 1: Empty Page",
"Start with a blank page",
[]
)
# Step 2: Apply template
print("\n2. Apply template")
create_visual_mockup(
str(output_dir / "workflow_02_template.png"),
"Step 2: Apply Template",
"Add placeholder blocks using a template",
[
('placeholder', 10, 10, 90, 90, 'Drop Here'),
('placeholder', 110, 10, 90, 90, 'Drop Here'),
('placeholder', 10, 110, 90, 90, 'Drop Here'),
('placeholder', 110, 110, 90, 90, 'Drop Here')
]
)
# Step 3: Add images
print("\n3. Add images")
create_visual_mockup(
str(output_dir / "workflow_03_images.png"),
"Step 3: Add Images",
"Drag and drop images onto placeholders",
[
('image', 10, 10, 90, 90, 'Photo 1'),
('image', 110, 10, 90, 90, 'Photo 2'),
('image', 10, 110, 90, 90, 'Photo 3'),
('placeholder', 110, 110, 90, 90, 'Drop Here')
]
)
# Step 4: Final layout
print("\n4. Final layout")
create_visual_mockup(
str(output_dir / "workflow_04_final.png"),
"Step 4: Final Layout",
"Complete page with all images and text",
[
('image', 10, 10, 90, 90, 'Photo 1'),
('image', 110, 10, 90, 90, 'Photo 2'),
('image', 10, 110, 90, 90, 'Photo 3'),
('image', 110, 110, 90, 90, 'Photo 4'),
('text', 10, 210, 190, 20, 'My Photo Album - Summer 2024')
]
)
def generate_template_examples():
"""Generate template system examples"""
print("\n" + "="*60)
print("Generating Template Examples")
print("="*60)
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
# Grid template
print("\n1. Grid_2x2 Template")
create_visual_mockup(
str(output_dir / "template_grid_2x2.png"),
"Grid_2x2 Template",
"Built-in 2x2 grid template",
[
('placeholder', 10, 10, 95, 133, ''),
('placeholder', 105, 10, 95, 133, ''),
('placeholder', 10, 143, 95, 134, ''),
('placeholder', 105, 143, 95, 134, '')
]
)
# Single large template
print("\n2. Single_Large Template")
create_visual_mockup(
str(output_dir / "template_single_large.png"),
"Single_Large Template",
"Built-in single large image template",
[
('placeholder', 10, 10, 190, 240, 'Large Image'),
('text', 10, 260, 190, 25, 'Title')
]
)
def generate_project_structure_diagram():
"""Generate project structure visualization"""
print("\n" + "="*60)
print("Generating Project Structure Diagram")
print("="*60)
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
try:
from PIL import Image, ImageDraw, ImageFont
width, height = 800, 600
img = Image.new('RGB', (width, height), color='white')
draw = ImageDraw.Draw(img)
try:
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16)
title_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 20)
except:
font = ImageFont.load_default()
title_font = ImageFont.load_default()
# Title
draw.text((20, 20), "pyPhotoAlbum Project Structure", fill='black', font=title_font)
# Draw structure
structure = [
(50, "Project", 60),
(100, "├─ Page 1", 100),
(150, "│ ├─ PageLayout", 140),
(200, "│ │ ├─ ImageData", 180),
(250, "│ │ ├─ TextBoxData", 220),
(300, "│ │ └─ PlaceholderData", 260),
(100, "├─ Page 2", 320),
(100, "└─ AssetManager", 360),
(150, " └─ assets/", 400),
]
for x, text, y in structure:
draw.text((x, y), text, fill='#333333', font=font)
# Draw connecting lines (simplified)
draw.line([(60, 90), (60, 380)], fill='#666666', width=2)
draw.line([(110, 130), (110, 280)], fill='#666666', width=2)
path = output_dir / "project_structure.png"
img.save(str(path))
print(f" Created: {path}")
except Exception as e:
print(f" Error creating diagram: {e}")
def main():
"""Generate all documentation screenshots"""
print("\n" + "="*60)
print("pyPhotoAlbum - Generate Documentation Screenshots")
print("="*60)
print("\nThis script creates visual examples for documentation.")
print("For actual application screenshots, run the app and")
print("use a screen capture tool.\n")
try:
# Create output directory
output_dir = Path(__file__).parent / "screenshots"
output_dir.mkdir(exist_ok=True)
print(f"Output directory: {output_dir}")
# Generate examples
generate_layout_examples()
generate_feature_examples()
generate_workflow_example()
generate_template_examples()
generate_project_structure_diagram()
print("\n" + "="*60)
print("Screenshot generation complete!")
print("="*60)
print(f"\nGenerated files are in: {output_dir}")
print("\nThese mockups can be used in documentation to illustrate:")
print(" - Page layouts")
print(" - Template system")
print(" - Feature demonstrations")
print(" - Workflow examples")
except Exception as e:
print(f"\nError generating screenshots: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()