import gradio as gr import os import json from pathlib import Path import matplotlib.pyplot as plt from PIL import Image import numpy as np import glob # Set holiday theme colors HOLIDAY_THEME = { "primary": "#c41e3a", # Christmas red "secondary": "#0a5c36", # Christmas green "accent": "#f4c542", # Gold accent "background": "#fff9f0", # Warm off-white "text": "#2c1810", # Dark brown text } def load_txt_file(filepath): """Load and display text file content.""" try: with open(filepath, 'r') as f: content = f.read() return content except: return "File not found" def load_json_file(filepath): """Load and display JSON file content.""" try: with open(filepath, 'r') as f: data = json.load(f) return json.dumps(data, indent=2) except: return "JSON file not found" def create_holiday_css(): """Create holiday-themed CSS.""" return f""" .gradio-container {{ background: linear-gradient(135deg, {HOLIDAY_THEME['background']} 0%, #f8f4e9 100%); font-family: 'Segoe UI', 'Arial', sans-serif; }} .gradio-header {{ background: linear-gradient(90deg, {HOLIDAY_THEME['primary']}, {HOLIDAY_THEME['secondary']}); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; text-align: center; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }} .holiday-title {{ font-size: 2.5em; font-weight: bold; margin-bottom: 10px; text-shadow: 2px 2px 4px rgba(0,0,0,0.2); }} .holiday-subtitle {{ font-size: 1.2em; opacity: 0.9; }} .tab-button {{ background: {HOLIDAY_THEME['secondary']} !important; color: white !important; border-radius: 5px !important; margin: 2px !important; }} .tab-button.selected {{ background: {HOLIDAY_THEME['primary']} !important; box-shadow: 0 0 10px {HOLIDAY_THEME['accent']} !important; }} .holiday-card {{ background: white; border-radius: 10px; padding: 15px; margin: 10px 0; box-shadow: 0 4px 8px rgba(0,0,0,0.1); border-left: 5px solid {HOLIDAY_THEME['primary']}; }} .gallery-container {{ background: white; padding: 20px; border-radius: 15px; box-shadow: 0 6px 16px rgba(0,0,0,0.1); }} .large-image {{ max-width: 100% !important; height: auto !important; border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); }} .large-collage {{ max-width: 100% !important; height: auto !important; border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.15); }} .collage-container {{ display: flex; flex-direction: column; align-items: center; gap: 15px; padding: 20px; }} .image-container {{ display: flex; flex-direction: column; align-items: center; gap: 15px; padding: 20px; }} """ def parse_filename(filename): """Parse Z Image Turbo filenames to extract parameters.""" # Format: img_256_steps_guidance_seed.png parts = filename.replace('.png', '').split('_') if len(parts) >= 5: return { 'resolution': parts[1], 'steps': parts[2], 'guidance': parts[3], 'seed': parts[4] if len(parts) > 4 else '1' } return {} def get_image_files(images_path): """Get all image files organized by guidance scale.""" if not os.path.exists(images_path): return {} # Organize images by guidance scale guidance_images = { "0.0": [], "1.0": [], "2.0": [], "3.0": [], "4.0": [], "all": [] } all_images = sorted(glob.glob(os.path.join(images_path, "img_256_*.png"))) for img_path in all_images: filename = os.path.basename(img_path) params = parse_filename(filename) if params: guidance = params['guidance'] if guidance in guidance_images: guidance_images[guidance].append(img_path) guidance_images["all"].append(img_path) return guidance_images def get_collage_images(collage_path): """Get all collage images.""" collage_files = glob.glob(os.path.join(collage_path, "*.png")) return collage_files def create_experiment_summary(): """Create a summary of the Z Image Turbo experiment.""" summary = """ # Z Image Turbo Experiment Summary ## Parameters Tested: - **Resolution**: Fixed at 256x256 - **Steps**: 25, 50, 100, 200, 300 - **Guidance Scale**: 0.0, 1.0, 2.0, 3.0, 4.0 - **Seeds**: 1-5 for each combination ## Total Images Generated: - 5 steps × 5 guidance scales × 5 seeds = **125 images** ## File Naming Convention: `img_256_[steps]_[guidance]_[seed].png` ## Collages Created: 1. All variations per guidance scale 2. Step comparisons per guidance scale 3. Comprehensive guidance grid 4. Individual step collages ## Analysis: This experiment systematically tests the effect of step count and guidance scale on image generation quality with Z Image Turbo model at 256x256 resolution. """ return summary # Main app with gr.Blocks() as app: # Header with gr.Column(elem_classes="gradio-header"): gr.Markdown( """
🎄 Z Image Turbo Holiday Showcase 🎁
A festive exploration of image generation parameters at 256x256 resolution
""" ) with gr.Tabs() as tabs: # Tab 1: Experiment Overview - SHOWING ALL GUIDANCE SCALES with gr.TabItem("🎯 Experiment Overview", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# 📊 Experiment Configuration") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### Parameters Matrix") params_html = """
Steps Guidance Scale Seeds
250.01-5
501.01-5
1002.01-5
2003.01-5
3004.01-5
""" gr.HTML(params_html) with gr.Column(scale=2): gr.Markdown("### Generated Images Sample Grid") gr.Markdown("*Visual comparison of all 5 guidance scales across different step counts*") # Create comprehensive sample grid showing ALL guidance scales images_path = "./256_Batch/images" if os.path.exists(images_path): # Create a 5x5 grid (5 steps × 5 guidance scales) guidance_scales = ["0.0", "1.0", "2.0", "3.0", "4.0"] steps = ["25", "50", "100", "200", "300"] fig, axes = plt.subplots(5, 5, figsize=(16, 16)) axes = axes.flatten() img_idx = 0 for step in steps: for guidance in guidance_scales: if img_idx >= 25: break pattern = f"img_256_{step}_{guidance}_1.png" image_files = glob.glob(os.path.join(images_path, pattern)) if image_files: try: img = Image.open(image_files[0]) ax = axes[img_idx] ax.imshow(img) ax.axis('off') ax.set_title(f"Steps:{step}\nGuidance:{guidance}", fontsize=11, color=HOLIDAY_THEME['primary'], fontweight='bold', pad=10) except: axes[img_idx].axis('off') axes[img_idx].text(0.5, 0.5, f"Image\nNot Found", ha='center', va='center', fontsize=9, color='red') else: axes[img_idx].axis('off') axes[img_idx].text(0.5, 0.5, f"Steps:{step}\nGuidance:{guidance}", ha='center', va='center', fontsize=9, color=HOLIDAY_THEME['secondary']) img_idx += 1 plt.tight_layout() plt.subplots_adjust(wspace=0.05, hspace=0.25) gr.Plot(fig) gr.Markdown("**Note:** Each cell shows seed #1 for that parameter combination. Use the Image Gallery tab to see all seeds.") else: gr.Markdown("⚠️ Images directory not found.") gr.Markdown("---") gr.Markdown(create_experiment_summary()) # Tab 2: Image Gallery (ORGANIZED LIKE COLLAGES GALLERY) with gr.TabItem("🖼️ Image Gallery", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# 🎨 Complete Image Gallery") gr.Markdown("*Browse all 125 images organized by guidance scale*") images_path = "./256_Batch/images" if os.path.exists(images_path): # Get all images organized by guidance scale guidance_images = get_image_files(images_path) if guidance_images["all"]: # Create tabs for each guidance scale image_tabs = gr.Tabs() with image_tabs: # Tab for "All Images" with gr.TabItem("All Images (125 total)"): gr.Markdown("### All Generated Images") gr.Markdown(f"*Total: {len(guidance_images['all'])} images*") # Display all images in a grid all_images_grid = gr.Gallery( value=guidance_images["all"], label="All Z Image Turbo Generated Images", columns=5, rows="auto", object_fit="contain", height="auto" ) # Tabs for each guidance scale for guidance in ["0.0", "1.0", "2.0", "3.0", "4.0"]: images = guidance_images[guidance] if images: with gr.TabItem(f"Guidance Scale: {guidance} ({len(images)} images)"): gr.Markdown(f"### Guidance Scale: {guidance}") gr.Markdown(f"*Showing {len(images)} images*") # Create a tab within the tab for organized viewing step_tabs = gr.Tabs() with step_tabs: # Group images by steps for step in ["25", "50", "100", "200", "300"]: step_images = [img for img in images if f"_{step}_{guidance}_" in img] if step_images: with gr.TabItem(f"{step} steps ({len(step_images)} images)"): # Display images for this step step_gallery = gr.Gallery( value=step_images, label=f"Guidance: {guidance}, Steps: {step}", columns=5, rows="auto", object_fit="contain", height="auto" ) gr.Markdown(f"**Seeds:** 1-{len(step_images)} | **Total:** {len(step_images)} images") else: with gr.TabItem(f"Guidance Scale: {guidance} (0 images)"): gr.Markdown(f"### No images found for guidance scale: {guidance}") else: gr.Markdown("No images found in the specified directory.") else: gr.Markdown("⚠️ Images directory not found.") # Tip for users with gr.Row(): gr.Markdown("**Tip:** Click on any image to view it larger. Navigate through tabs to see images organized by guidance scale and step count.") # Tab 3: Collages Showcase (LARGER DISPLAY) with gr.TabItem("🖼️ Collages", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# 🎪 Collage Showcase") gr.Markdown("*Comprehensive visual summaries - Click to view full size*") collage_path = "./256_Batch/collages" if os.path.exists(collage_path): collage_files = get_collage_images(collage_path) if collage_files: # Create tabs for each collage for better organization collage_tabs = gr.Tabs() with collage_tabs: for idx, collage in enumerate(collage_files): filename = os.path.basename(collage) with gr.TabItem(filename): # Description based on filename description = { "256_all_variations_G": "All image variations at specific guidance scale", "256_steps_comparison": "Comparison across different step counts", "256_comprehensive_guidance_grid": "Complete guidance scale comparison", "collage_steps": "Step-by-step progression collage", "resolution_256_grid": "Complete 256x256 resolution grid", "256_summary": "Experiment summary collage", "variation_comparison": "Variation comparison across parameters", "test_collage": "Test collage for layout verification" } desc = "Visual summary collage" for key in description: if key in filename: desc = description[key] break # Display collage with larger size with gr.Column(elem_classes="collage-container"): gr.Markdown(f"### {filename}") gr.Markdown(f"**Description:** {desc}") # Larger image display collage_image = gr.Image( collage, label=f"Full Size: {filename}", height=600, # Increased height width="auto", elem_classes="large-collage", interactive=False ) # File info gr.Markdown(f"**File:** `{filename}`") else: gr.Markdown("No collages found in the specified directory.") else: gr.Markdown("⚠️ Collages directory not found. Please update the path.") # Tab 4: Configuration Files with gr.TabItem("📁 Configuration Files", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# ⚙️ Experiment Configuration Files") with gr.Row(): with gr.Column(): gr.Markdown("### Batch Generation Script") txt_content = gr.Code( label="generate_holiday_batch_256.txt", language=None, interactive=False ) def load_txt(): return load_txt_file("./generate_holiday_batch_256.txt") load_txt_btn = gr.Button("Load File", variant="primary") load_txt_btn.click(load_txt, outputs=txt_content) with gr.Column(): gr.Markdown("### Reconstruction Log") json_content = gr.Code( label="reconstructed_log_20251223_140645.json", language="json", interactive=False ) def load_json(): return load_json_file("./reconstructed_log_20251223_140645.json") load_json_btn = gr.Button("Load File", variant="primary") load_json_btn.click(load_json, outputs=json_content) # Tab 5: Analysis & Insights with gr.TabItem("📈 Analysis", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# 🔍 Analysis & Insights") with gr.Row(): with gr.Column(): gr.Markdown("## Key Finding: Optimal Step Count") # Visual demonstration of the 200-step peak optimal_steps_html = """

🔍 Detail Quality vs Step Count

25-50 Steps

Quick generation
Basic details

100-200 Steps

Optimal balance
Peak detail quality

300+ Steps

Diminishing returns
High compute cost

🎯 Peak Performance at 200 Steps

Maximum detail quality with optimal compute efficiency

Beyond 200 steps: minimal quality improvement, significant time increase

""" gr.HTML(optimal_steps_html) gr.Markdown("## Detailed Observations") insights = """ ### 1. **Guidance Scale Impact** - **0.0**: Maximum creativity, highly diverse outputs, less coherent - **1.0-2.0**: Balanced creativity and coherence, most versatile - **3.0-4.0**: Highly guided, consistent but less creative outputs ### 2. **Step Count Impact** ⭐ **KEY FINDING** - **25-50 steps**: Quick generation, basic details, useful for prototyping - **100-200 steps**: **Optimal quality/speed balance**, peak detail quality - **300 steps**: Maximum refinement with **diminishing returns** ### 3. **Visual Trends** - Lower guidance = more artistic variation, experimental results - Higher steps = better detail preservation, especially in holiday elements - Seed consistency strong across all parameter combinations ### 4. **Holiday Theme Performance** - Model captures festive elements well at medium guidance (1.0-2.0) - Color schemes adapt naturally to guidance levels - Consistent style maintained across parameter variations """ gr.Markdown(insights) with gr.Column(): gr.Markdown("## Recommendations") recommendations = """ ## 🎯 Optimal Settings for 256x256: ### For Holiday Art Projects: - **Guidance: 1.5-2.0** with **150-200 steps** - Explore seeds 1-3 for creative variations - Best for: Holiday cards, festive decorations ### For Consistent Brand Assets: - **Guidance: 3.0** with **200 steps** - Fixed seed for reproducibility - Best for: Marketing materials, product designs ### For Quick Prototyping: - **Guidance: 2.0** with **50-100 steps** - Batch generate with seeds 1-5 - Best for: Concept exploration, mood boards ### ⭐ **Best Overall Setting:** - **Guidance: 2.0** with **200 steps**, Seed: 1 - Combines good creativity with excellent detail - Computationally efficient ### Holiday-Specific Tips: - Higher guidance (3.0-4.0) for traditional holiday scenes - Lower guidance (0.0-1.0) for abstract festive art - Medium steps (150-200) for optimal detail in ornaments/lights """ gr.Markdown(recommendations) gr.Markdown("---") # Performance Metrics with emphasis on 200-step peak with gr.Row(): gr.Markdown("### 📊 Performance Metrics Analysis") metrics_html = f"""

⏱️ Generation Time

25 → 300 steps

Linear increase: ~2× time per 100 steps

200 steps: Sweet spot for time/quality

🎨 Output Diversity

Highest at G=0.0

Decreases with guidance scale increase

G=2.0: Balanced diversity/coherence

🔍 Detail Quality ★

Peaks at 200 steps

Key Finding: Diminishing returns beyond 200

300 steps: Only 5-10% better than 200 steps

📈 Return on Investment (Steps vs Quality)

100 Steps

85% Quality
100% Time

200 Steps

100% Quality
200% Time

300 Steps

105% Quality
300% Time

200 steps provides the best balance of detail quality and generation time

""" gr.HTML(metrics_html) # Tab 6: Step Comparison Visual with gr.TabItem("⚡ Step Comparison", elem_classes="tab-button"): with gr.Column(): gr.Markdown("# ⚡ Step Count Comparison") gr.Markdown("*Visual demonstration of detail quality peaking at 200 steps*") images_path = "./256_Batch/images" if os.path.exists(images_path): # Create comparison of same parameters at different steps guidance_to_show = "2.0" # Show at guidance 2.0 seed_to_show = "1" comparison_steps = ["25", "50", "100", "200", "300"] # Create comparison grid fig, axes = plt.subplots(1, 5, figsize=(20, 4)) for idx, step in enumerate(comparison_steps): pattern = f"img_256_{step}_{guidance_to_show}_{seed_to_show}.png" image_files = glob.glob(os.path.join(images_path, pattern)) if image_files: img = Image.open(image_files[0]) ax = axes[idx] ax.imshow(img) ax.axis('off') # Highlight 200 steps if step == "200": title_color = HOLIDAY_THEME['accent'] title_weight = 'bold' # Add star marker ax.set_title(f"⭐ {step} Steps ⭐", fontsize=12, color=title_color, fontweight=title_weight, pad=10) else: title_color = HOLIDAY_THEME['primary'] title_weight = 'normal' ax.set_title(f"{step} Steps", fontsize=11, color=title_color, fontweight=title_weight, pad=10) else: axes[idx].axis('off') axes[idx].text(0.5, 0.5, f"{step} Steps\nNot Found", ha='center', va='center', fontsize=10, color=HOLIDAY_THEME['secondary']) plt.tight_layout() gr.Plot(fig) # Explanation gr.Markdown(""" ## 📊 Observation: Detail Quality Progression ### Step-by-Step Improvement: 1. **25-50 Steps**: Basic shapes and colors, lacks fine details 2. **100 Steps**: Good detail, coherent composition 3. **200 Steps**: **Peak detail quality** - optimal balance 4. **300 Steps**: Minimal improvement over 200 steps ### Key Insight: - **200 steps** provides 95% of maximum possible quality - **300 steps** only adds 5% more detail at 50% more compute time - **Best ROI**: 200 steps for holiday-themed generations """) else: gr.Markdown("⚠️ Images directory not found for comparison.") if __name__ == "__main__": print("🎄 Z Image Turbo Holiday Showcase App") print("=" * 50) print("Now showing ALL guidance scales and ALL 125 images in organized galleries!") # Debug: Check if images and collages exist images_path = "./256_Batch/images" if os.path.exists(images_path): image_files = glob.glob(os.path.join(images_path, "*.png")) print(f"✓ Found {len(image_files)} images in: {images_path}") # Show distribution by guidance scale guidance_images = get_image_files(images_path) for guidance in ["0.0", "1.0", "2.0", "3.0", "4.0"]: print(f" • Guidance {guidance}: {len(guidance_images[guidance])} images") else: print(f"✗ WARNING: Images path not found: {images_path}") collage_path = "./256_Batch/collages" if os.path.exists(collage_path): collage_files = glob.glob(os.path.join(collage_path, "*.png")) print(f"✓ Found {len(collage_files)} collages in: {collage_path}") else: print(f"✗ WARNING: Collages path not found: {collage_path}") print("\nThe app will be available at: http://localhost:7860") print("- Tab 1: Shows ALL guidance scales (0.0-4.0) for each step count in 5×5 grid") print("- Tab 2: Shows ALL 125 images in organized tabs (by guidance scale & steps)") print("- Tab 3: Shows LARGE collages in dedicated tabs") print("=" * 50) print("\n") app.launch( server_name="0.0.0.0", server_port=7860, share=False, css=create_holiday_css(), theme=gr.themes.Soft() )