Phramer_AI / app.py
Malaji71's picture
Update app.py
02c3790 verified
raw
history blame
12.2 kB
"""
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.",
'<div style="text-align: center; padding: 1rem;"><div style="font-size: 2rem; color: #ccc;">--</div><div style="font-size: 0.875rem; color: #999;">Quality Score</div></div>'
)
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.",
'<div style="text-align: center; padding: 1rem; color: red;"><div style="font-size: 2rem;">0</div><div style="font-size: 0.875rem;">Error</div></div>'
)
def clear_interface() -> Tuple[str, str, str]:
"""Clear all interface outputs and free memory"""
clean_memory()
logger.info("Interface cleared")
return (
"",
"",
'<div style="text-align: center; padding: 1rem;"><div style="font-size: 2rem; color: #ccc;">--</div><div style="font-size: 0.875rem; color: #999;">Quality Score</div></div>'
)
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("""
<div class="main-header">
<div class="main-title">Frame 0 Laboratory for MIA</div>
<div class="subtitle">Advanced Image Analysis & FLUX Prompt Optimization</div>
</div>
""")
# 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='<div style="text-align: center; padding: 1rem;"><div style="font-size: 2rem; color: #ccc;">--</div><div style="font-size: 0.875rem; color: #999;">Quality Score</div></div>'
)
# 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()