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 | |
) |