Spaces:
Running
on
Zero
Running
on
Zero
| 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(""" | |
| <div class="main-title"> | |
| 🤖 IA para todos | |
| </div> | |
| """) | |
| gr.HTML(""" | |
| <div class="subtitle"> | |
| "Porque cuando no tienes nada en la cabeza, te preocupas de la tipografía?" | |
| </div> | |
| """) | |
| 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 | |
| ) |