""" Frame 0 Laboratory for MIA - Main Gradio Interface FLUX Prompt Optimizer with clean, professional interface """ import gradio as gr import logging import warnings import os from typing import Tuple from config import APP_CONFIG, ENVIRONMENT from processor import process_image_simple, flux_optimizer from utils import setup_logging, clean_memory # Configure environment warnings.filterwarnings("ignore", category=FutureWarning) warnings.filterwarnings("ignore", category=UserWarning) os.environ["TOKENIZERS_PARALLELISM"] = "false" # Setup logging setup_logging(ENVIRONMENT["log_level"]) logger = logging.getLogger(__name__) def process_image_interface(image) -> Tuple[str, str, str]: """ Main interface function for image processing Args: image: Input image from Gradio interface Returns: Tuple of (prompt, analysis_report, score_html) """ try: if image is None: return ( "Please upload an image to analyze", "No image provided for analysis.", '
--
Quality Score
' ) logger.info("Processing image through interface") prompt, report, score_html = process_image_simple(image) return prompt, report, score_html except Exception as e: logger.error(f"Interface processing error: {e}", exc_info=True) error_msg = f"Processing failed: {str(e)}" return ( "❌ Processing failed", f"**Error:** {error_msg}\n\nPlease try again with a different image.", '
0
Error
' ) def clear_interface() -> Tuple[str, str, str]: """Clear all interface outputs and free memory""" clean_memory() logger.info("Interface cleared") return ( "", "", '
--
Quality Score
' ) def get_stats_info() -> str: """Get current processing statistics""" try: stats = flux_optimizer.get_stats() stats_text = f"""**Processing Statistics:** • **Total Images:** {stats['total_processed']} • **Successful:** {stats['successful_analyses']} • **Failed:** {stats['failed_analyses']} • **Success Rate:** {stats['success_rate']:.1%} • **Average Time:** {stats['average_processing_time']:.1f}s • **Device:** {stats['device_info']['device'].upper()} """ return stats_text except Exception as e: logger.error(f"Stats retrieval error: {e}") return "Statistics unavailable" def create_interface(): """Create the main Gradio interface""" # Custom CSS for clean, professional look css = """ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); .gradio-container { max-width: 1400px !important; margin: 0 auto !important; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important; background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important; } /* Text visibility fixes */ .markdown-text, .markdown-text *, .prose, .prose *, .gr-markdown, .gr-markdown *, div[class*="markdown"], div[class*="markdown"] * { color: #1f2937 !important; } .markdown-text h1, .markdown-text h2, .markdown-text h3, .prose h1, .prose h2, .prose h3, .gr-markdown h1, .gr-markdown h2, .gr-markdown h3 { color: #111827 !important; font-weight: 600 !important; } .markdown-text p, .markdown-text li, .prose p, .prose li, .gr-markdown p, .gr-markdown li { color: #374151 !important; } .markdown-text strong, .prose strong, .gr-markdown strong { color: #111827 !important; font-weight: 600 !important; } /* Header styling */ .main-header { text-align: center; padding: 2.5rem 0 3rem 0; background: linear-gradient(135deg, #1e293b 0%, #334155 50%, #475569 100%); color: white; margin: -2rem -2rem 2rem -2rem; border-radius: 0 0 24px 24px; box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.2); } .main-title { font-size: 2.5rem !important; font-weight: 700 !important; margin: 0 0 0.5rem 0 !important; letter-spacing: -0.025em !important; color: #ffffff !important; } .subtitle { font-size: 1.125rem !important; font-weight: 400 !important; opacity: 0.9 !important; margin: 0 !important; color: #cbd5e1 !important; } /* Prompt output styling */ .prompt-output { font-family: 'SF Mono', 'Monaco', 'Consolas', monospace !important; font-size: 14px !important; line-height: 1.6 !important; background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%) !important; border: 2px solid #e2e8f0 !important; border-radius: 12px !important; padding: 1.5rem !important; box-shadow: 0 4px 15px -2px rgba(0, 0, 0, 0.08) !important; transition: all 0.3s ease !important; color: #1f2937 !important; } .prompt-output:hover { box-shadow: 0 8px 25px -5px rgba(0, 0, 0, 0.12) !important; transform: translateY(-1px) !important; } /* Button styling */ .gr-button-primary { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important; border: none !important; color: white !important; font-weight: 500 !important; padding: 0.75rem 1.5rem !important; border-radius: 8px !important; transition: all 0.2s ease !important; } .gr-button-primary:hover { background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%) !important; transform: translateY(-1px) !important; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3) !important; } .gr-button-secondary { background: #f1f5f9 !important; border: 1px solid #cbd5e1 !important; color: #475569 !important; font-weight: 500 !important; border-radius: 8px !important; } .gr-button-secondary:hover { background: #e2e8f0 !important; border-color: #94a3b8 !important; } /* Image upload area */ .gr-file-upload { border: 2px dashed #cbd5e1 !important; border-radius: 12px !important; background: #f8fafc !important; } /* Info boxes */ .info-box { background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border: 1px solid #0284c7; border-radius: 12px; padding: 1rem; margin: 1rem 0; } """ with gr.Blocks( theme=gr.themes.Soft( primary_hue="blue", secondary_hue="slate", neutral_hue="slate" ), title="Frame 0 Laboratory for MIA", css=css ) as interface: # Header gr.HTML("""
Frame 0 Laboratory for MIA
Advanced Image Analysis & FLUX Prompt Optimization
""") # Main interface with gr.Row(): # Left column - Input with gr.Column(scale=1): gr.Markdown("## Image Analysis") image_input = gr.Image( label="Upload Image for Analysis", type="pil", height=400 ) with gr.Row(): analyze_btn = gr.Button( "🔍 Analyze Image", variant="primary", size="lg" ) clear_btn = gr.Button( "🗑️ Clear", variant="secondary", size="lg" ) # Information panel gr.Markdown(""" ### How it works: **1. Image Analysis:** Advanced AI models analyze your image to understand content, composition, and style. **2. FLUX Optimization:** Applies proven rules for FLUX image generation including camera settings, lighting, and technical parameters. **3. Quality Scoring:** Evaluates the optimized prompt across multiple dimensions for best results. **Supported formats:** JPG, PNG, WebP up to 1024px """) # Statistics (collapsible) with gr.Accordion("📊 Processing Stats", open=False): stats_output = gr.Markdown(value="No processing completed yet.") refresh_stats_btn = gr.Button("Refresh Stats", size="sm") refresh_stats_btn.click( fn=get_stats_info, outputs=stats_output ) # Right column - Output with gr.Column(scale=1): gr.Markdown("## Results") # Score display score_output = gr.HTML( value='
--
Quality Score
' ) # Optimized prompt prompt_output = gr.Textbox( label="🎯 Optimized FLUX Prompt", placeholder="Upload an image to generate an optimized prompt...", lines=8, max_lines=15, elem_classes=["prompt-output"], show_copy_button=True ) # Analysis report with gr.Accordion("📋 Detailed Analysis", open=True): info_output = gr.Markdown(value="") # Event handlers analyze_btn.click( fn=process_image_interface, inputs=[image_input], outputs=[prompt_output, info_output, score_output] ) clear_btn.click( fn=clear_interface, outputs=[prompt_output, info_output, score_output] ) # Footer gr.Markdown(""" --- **Frame 0 Laboratory for MIA** • Advanced AI Research & Development This tool uses state-of-the-art vision-language models to analyze images and generate optimized prompts for FLUX image generation. The system applies proven optimization rules including camera configurations, lighting setups, and technical parameters for best results. """) return interface def main(): """Main application entry point""" logger.info("Starting Frame 0 Laboratory for MIA") # Create and launch interface demo = create_interface() # Launch configuration launch_config = { "server_name": "0.0.0.0", "server_port": 7860, "show_error": True, "show_tips": True, "enable_queue": True } # Add share option for Spaces if ENVIRONMENT["is_spaces"]: launch_config["share"] = False # Spaces handles sharing else: launch_config["share"] = True # Enable sharing for local logger.info(f"Launching on port {launch_config['server_port']}") demo.launch(**launch_config) if __name__ == "__main__": main()