yogesh882's picture
Upload 1036 files
d69fefe verified
"""
Web-based interface for photo mosaic creation using Gradio
Author: [Your Name]
Date: November 2025
Version: 2.0
"""
import gradio as gr
import numpy as np
from PIL import Image
import time
from pathlib import Path
# Import custom mosaic generation modules
from mosaic_generator import (
TileManager,
MosaicBuilder,
compute_similarity_metrics,
format_metrics,
config
)
def initialize_tile_system():
"""Load and prepare tile collection for mosaic generation"""
print("🎨 Loading tile collection...")
manager = TileManager(tiles_path=config.DEFAULT_TILE_DIRECTORY)
print(f"βœ“ Successfully loaded {len(manager)} tile images")
return manager
# Global tile management system
tile_system = initialize_tile_system()
def process_mosaic_request(uploaded_img, rows, cols):
"""
Process user request to generate photo mosaic
Parameters:
uploaded_img: PIL Image object from user upload
rows: Number of rows in mosaic grid
cols: Number of columns in mosaic grid
Returns:
tuple: Generated mosaic image and status information
"""
# Input validation
if uploaded_img is None:
return None, "⚠️ No image provided. Please upload an image first."
try:
# Initialize mosaic generator with user-specified grid
generator = MosaicBuilder(tile_system, grid_layout=(rows, cols))
# Track execution time
time_start = time.time()
result_mosaic = generator.create_mosaic(uploaded_img)
time_elapsed = time.time() - time_start
# Prepare original image for metric comparison
original_resized = uploaded_img.resize(
(result_mosaic.shape[1], result_mosaic.shape[0]),
Image.Resampling.LANCZOS
)
# Calculate quality metrics
quality_metrics = compute_similarity_metrics(original_resized, result_mosaic)
# Build status report
status_report = []
status_report.append("βœ… Mosaic creation completed successfully!")
status_report.append("")
status_report.append(f"⏱️ Execution time: {time_elapsed:.3f}s")
status_report.append(f"πŸ“ Grid configuration: {rows}Γ—{cols} = {rows * cols} tiles")
status_report.append(f"🎨 Available tiles: {len(tile_system)}")
status_report.append("")
status_report.append(format_metrics(quality_metrics))
status_report.append("")
status_report.append(f"πŸ–ΌοΈ Result dimensions: {result_mosaic.shape[1]}Γ—{result_mosaic.shape[0]} pixels")
status_text = "\n".join(status_report)
# Convert numpy array to PIL for display
output_img = Image.fromarray(result_mosaic)
return output_img, status_text
except Exception as error:
error_report = f"❌ Processing failed: {str(error)}"
print(error_report)
import traceback
traceback.print_exc()
return None, error_report
def build_interface():
"""Construct the Gradio web interface"""
interface = gr.Blocks(title=config.UI_TITLE, theme=gr.themes.Soft())
with interface:
gr.Markdown(f"# {config.UI_TITLE}")
gr.Markdown(config.UI_DESCRIPTION)
with gr.Row():
# Left panel - inputs and controls
with gr.Column(scale=1):
gr.Markdown("### πŸ“€ Source Image")
source_image = gr.Image(
label="Upload your image",
type="pil",
height=400
)
gr.Markdown("### βš™οΈ Grid Configuration")
row_slider = gr.Slider(
minimum=config.MIN_GRID_SIZE,
maximum=config.MAX_GRID_SIZE,
value=config.DEFAULT_GRID_SIZE[0],
step=1,
label="Vertical tiles (rows)"
)
col_slider = gr.Slider(
minimum=config.MIN_GRID_SIZE,
maximum=config.MAX_GRID_SIZE,
value=config.DEFAULT_GRID_SIZE[1],
step=1,
label="Horizontal tiles (columns)"
)
submit_btn = gr.Button(
"🎨 Create Mosaic",
variant="primary",
size="lg"
)
# Right panel - outputs
with gr.Column(scale=1):
gr.Markdown("### πŸ“₯ Generated Mosaic")
result_image = gr.Image(
label="Your mosaic",
type="pil",
height=400
)
result_info = gr.Textbox(
label="Processing Details",
lines=15,
max_lines=20
)
# Add example images if available
test_image_path = Path("tests/test_512x512.png")
if test_image_path.exists():
gr.Markdown("### πŸ“Έ Sample Images")
sample_configs = []
if Path("tests/test_256x256.png").exists():
sample_configs.append(["tests/test_256x256.png", 16, 16])
if test_image_path.exists():
sample_configs.append(["tests/test_512x512.png", 32, 32])
sample_configs.append(["tests/test_512x512.png", 48, 48])
if sample_configs:
gr.Examples(
examples=sample_configs,
inputs=[source_image, row_slider, col_slider],
label="Try these examples"
)
# Application footer
gr.Markdown("""
**CS5130 Lab 5** | High-Performance Photo Mosaic System v2.0
""")
# Wire up the interface
submit_btn.click(
fn=process_mosaic_request,
inputs=[source_image, row_slider, col_slider],
outputs=[result_image, result_info]
)
return interface
def main():
"""Application entry point"""
print("\n" + "="*70)
print("πŸš€ Launching Optimized Photo Mosaic Generator")
print("="*70)
print(f"πŸ“Š Tile inventory: {len(tile_system)} images")
print(f"πŸ“ Standard grid: {config.DEFAULT_GRID_SIZE[0]}Γ—{config.DEFAULT_GRID_SIZE[1]}")
print(f"🌐 Access at: http://localhost:7860")
print("="*70 + "\n")
web_interface = build_interface()
web_interface.launch(
server_name="0.0.0.0",
server_port=7860,
share=False
)
if __name__ == "__main__":
main()