import gradio as gr import torch from PIL import Image import numpy as np from clip_interrogator import Config, Interrogator import logging import os from datetime import datetime import json # Configurar logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Configuración de modelos CLIP_MODELS = { "general": "ViT-L-14/openai", "flux": "ViT-L-14/openai", "midjourney": "ViT-H-14/laion2b_s32b_b79k", "stable_diffusion": "ViT-L-14/openai" } # Modos de interrogación INTERROGATION_MODES = { "fast": "Rápido (menos detallado)", "classic": "Clásico (equilibrado)", "best": "Mejor (más detallado)", "negative": "Negativo (lo que NO es)" } class ImagePromptGenerator: def __init__(self): self.interrogators = {} self.usage_count = 0 self.setup_models() def setup_models(self): """Inicializar modelos CLIP Interrogator""" try: logger.info("Inicializando modelos CLIP...") # Configurar modelo principal primero config = Config( clip_model_name="ViT-L-14/openai", download_cache=True, chunk_size=2048, quiet=False ) self.interrogators["general"] = Interrogator(config) logger.info("Modelo general inicializado") except Exception as e: logger.error(f"Error inicializando modelos: {e}") # Fallback simple config = Config(clip_model_name="ViT-L-14/openai") self.interrogators["general"] = Interrogator(config) def generate_prompt(self, image, model_type="general", mode="best"): """Generar prompt desde imagen""" try: if image is None: return "❌ Por favor, sube una imagen primero.", "" # Incrementar contador de uso self.usage_count += 1 # Convertir imagen if isinstance(image, np.ndarray): image = Image.fromarray(image) elif not isinstance(image, Image.Image): image = Image.open(image) # Asegurar RGB if image.mode != 'RGB': image = image.convert('RGB') # Usar interrogator general por ahora interrogator = self.interrogators["general"] # Generar prompt según el modo if mode == "fast": prompt = interrogator.interrogate_fast(image) elif mode == "classic": prompt = interrogator.interrogate_classic(image) else: # best y negative prompt = interrogator.interrogate(image) # Información adicional info = f""" **✅ Prompt generado exitosamente con IA para todos** - **Modelo:** {model_type.title()} - **Modo:** {INTERROGATION_MODES.get(mode, mode)} - **Usos totales:** {self.usage_count} - **Hora:** {datetime.now().strftime('%H:%M:%S')} *"Porque cuando no tienes nada en la cabeza, te preocupas de la tipografía?"* 😄 """ return prompt, info except Exception as e: logger.error(f"Error generando prompt: {e}") error_msg = f"❌ Error: {str(e)}" error_info = "*Cuando falla la IA, al menos la tipografía sigue siendo bonita* 📝" return error_msg, error_info # Inicializar generador generator = ImagePromptGenerator() def process_image(image, model_type, mode): """Función principal para procesar imagen""" prompt, info = generator.generate_prompt(image, model_type, mode) return prompt, info # Crear interfaz Gradio def create_interface(): # CSS personalizado para mejor tipografía custom_css = """ .gradio-container { max-width: 1200px !important; font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .prompt-output { font-family: 'JetBrains Mono', 'Courier New', monospace !important; font-size: 14px !important; line-height: 1.6 !important; background: #f8f9fa !important; border-radius: 8px !important; padding: 16px !important; } .main-title { text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-size: 2.5em !important; font-weight: bold !important; margin-bottom: 0.5em !important; } .subtitle { text-align: center; font-style: italic; color: #666; font-size: 1.1em; margin-bottom: 2em; } """ with gr.Blocks( theme=gr.themes.Soft(), title="IA para todos - Image to Prompt", css=custom_css ) as interface: # Header personalizado gr.HTML("""
🤖 IA para todos
""") gr.HTML("""
"Porque cuando no tienes nada en la cabeza, te preocupas de la tipografía?"
""") gr.Markdown(""" ### 🎨 Convierte cualquier imagen en prompts detallados para IA Sube una imagen y obtén prompts optimizados para Stable Diffusion, Midjourney, Flux y más. """) with gr.Row(): with gr.Column(scale=1): # Input section gr.Markdown("## 📤 Subir Imagen") image_input = gr.Image( label="Arrastra o selecciona una imagen", type="pil", height=300 ) # Configuración gr.Markdown("## ⚙️ Configuración") model_selector = gr.Dropdown( choices=["general", "stable_diffusion", "midjourney", "flux"], value="general", label="Modelo de IA objetivo", info="Selecciona la plataforma donde usarás el prompt" ) mode_selector = gr.Dropdown( choices=["fast", "classic", "best"], value="best", label="Modo de análisis", info="Equilibrio entre velocidad y precisión" ) # Botón generar generate_btn = gr.Button( "🚀 Generar Prompt Mágico", variant="primary", size="lg" ) with gr.Column(scale=1): # Output section gr.Markdown("## 📝 Tu Prompt Está Listo") prompt_output = gr.Textbox( label="Prompt generado (listo para copiar)", placeholder="Tu prompt aparecerá aquí... ✨", lines=8, max_lines=15, elem_classes=["prompt-output"], show_copy_button=True ) info_output = gr.Markdown( label="Información del proceso", value="" ) # Botones de acción with gr.Row(): clear_btn = gr.Button("🗑️ Limpiar", size="sm") # Footer con tu frase gr.Markdown(""" --- ### 💡 Consejos de Uso: - **General:** Para prompts universales que funcionan en cualquier lado - **Stable Diffusion:** Optimizado para SD 1.x, SDXL y derivados - **Midjourney:** Perfecto para estilos artísticos y creativos - **Flux:** Para el revolucionario modelo Flux de Black Forest Labs ### 🔧 Modos de Análisis: - **Rápido:** Análisis express, menos detallado pero veloz ⚡ - **Clásico:** El equilibrio perfecto entre velocidad y calidad ⚖️ - **Mejor:** Máxima precisión y detalle (recomendado) ⭐ --- ### 🎭 Hecho con amor (y buena tipografía) por IA para todos *"La IA nos ayuda con las ideas, nosotros nos preocupamos de que se vean bonitas"* ✨ """) # Event handlers generate_btn.click( fn=process_image, inputs=[image_input, model_selector, mode_selector], outputs=[prompt_output, info_output] ) clear_btn.click( fn=lambda: ("", ""), outputs=[prompt_output, info_output] ) return interface # Lanzar aplicación if __name__ == "__main__": interface = create_interface() interface.launch( server_name="0.0.0.0", server_port=7860, show_error=True )