Spaces:
Sleeping
Sleeping
| """ | |
| App de Mejora de Prompts para Generación de Imágenes | |
| Compatible con Gradio 6.0+ | |
| """ | |
| import gradio as gr | |
| from prompt_engine import PromptEnhancer, PromptBuilder, PromptAnalyzer | |
| from model_configs import MODEL_CONFIGS, ARTIST_STYLES, ENHANCEMENT_RULES | |
| # Inicializar componentes | |
| enhancer = PromptEnhancer() | |
| analyzer = PromptAnalyzer() | |
| # ===== FUNCIONES PRINCIPALES ===== | |
| def enhance_prompt(prompt: str, model: str, style: str, | |
| add_quality: bool, add_negative: bool) -> tuple: | |
| """Función principal de mejora de prompts""" | |
| if not prompt or not prompt.strip(): | |
| return ("⚠️ Por favor, ingresa un prompt", "", "", "", "") | |
| model_map = { | |
| "Stable Diffusion 1.5": "stable-diffusion-1.5", | |
| "Stable Diffusion XL": "sdxl", | |
| "FLUX.1": "flux", | |
| "Midjourney": "midjourney", | |
| "DALL-E 3": "dall-e-3" | |
| } | |
| model_key = model_map.get(model, "stable-diffusion-1.5") | |
| style_key = style.lower() if style and style != "Ninguno" else None | |
| result = enhancer.enhance_for_model( | |
| prompt=prompt, | |
| model=model_key, | |
| style=style_key, | |
| add_quality=add_quality, | |
| add_negative=add_negative | |
| ) | |
| analysis = result["analysis"] | |
| score_emoji = "🟢" if analysis["score"] >= 70 else "🟡" if analysis["score"] >= 40 else "🔴" | |
| suggestions_text = '\n'.join(analysis['suggestions']) if analysis['suggestions'] else '✅ ¡El prompt está bien estructurado!' | |
| analysis_text = f"""### 📊 Análisis del Prompt | |
| **Puntuación:** {score_emoji} {analysis['score']}/100 | |
| **Estadísticas:** | |
| - Palabras: {analysis['word_count']} | |
| - Caracteres: {analysis['char_count']} | |
| - Tokens estimados: {result['tokens_estimate']}/{result['max_tokens']} | |
| **Sugerencias:** | |
| {suggestions_text} | |
| """ | |
| variations = enhancer.suggest_variations(result["enhanced"], 3) | |
| variations_text = "\n\n".join([f"**Variación {i+1}:**\n`{v}`" for i, v in enumerate(variations)]) | |
| return ( | |
| result["enhanced"], | |
| result["negative_prompt"], | |
| analysis_text, | |
| variations_text, | |
| f"✅ Optimizado para: **{result['model']}**" | |
| ) | |
| def fix_prompt(prompt: str) -> tuple: | |
| """Corrige errores comunes en el prompt""" | |
| if not prompt or not prompt.strip(): | |
| return ("⚠️ Por favor, ingresa un prompt", "") | |
| fixed, fixes = enhancer.fix_common_errors(prompt) | |
| if fixes: | |
| fixes_text = "### 🔧 Correcciones aplicadas:\n" + "\n".join([f"- {f}" for f in fixes]) | |
| else: | |
| fixes_text = "### ✅ No se encontraron errores que corregir" | |
| return fixed, fixes_text | |
| def build_prompt(subject: str, style: str, lighting: str, mood: str, | |
| camera: str, quality_opts: list, extra_details: str) -> str: | |
| """Construye un prompt desde componentes""" | |
| if not subject or not subject.strip(): | |
| return "⚠️ Por favor, ingresa al menos un sujeto" | |
| builder = PromptBuilder() | |
| builder.set_subject(subject) | |
| if style and style != "Ninguno": | |
| builder.set_style(style.lower()) | |
| if lighting and lighting != "Ninguno": | |
| builder.set_lighting(lighting.lower()) | |
| if mood and mood != "Ninguno": | |
| builder.set_mood(mood.lower()) | |
| if camera and camera != "Ninguno": | |
| builder.set_camera(camera.lower()) | |
| if quality_opts: | |
| quality_map = { | |
| "Alta definición (8K)": ["8k uhd", "high resolution"], | |
| "Muy detallado": ["highly detailed", "intricate details"], | |
| "Masterpiece": ["masterpiece", "best quality"], | |
| "Fotografía profesional": ["professional photography", "DSLR"], | |
| "Arte de alta calidad": ["high quality art", "artstation"] | |
| } | |
| quality_terms = [] | |
| for opt in quality_opts: | |
| if opt in quality_map: | |
| quality_terms.extend(quality_map[opt]) | |
| builder.add_quality(quality_terms) | |
| if extra_details and extra_details.strip(): | |
| builder.add_details([extra_details.strip()]) | |
| return builder.build() | |
| def analyze_only(prompt: str) -> str: | |
| """Solo analiza el prompt sin mejorarlo""" | |
| if not prompt or not prompt.strip(): | |
| return "⚠️ Por favor, ingresa un prompt para analizar" | |
| analysis = analyzer.analyze(prompt) | |
| score = analysis["score"] | |
| if score >= 80: | |
| grade = "🏆 Excelente" | |
| elif score >= 60: | |
| grade = "👍 Bueno" | |
| elif score >= 40: | |
| grade = "⚠️ Mejorable" | |
| else: | |
| grade = "❌ Necesita trabajo" | |
| if analysis["issues"]: | |
| issue_names = { | |
| "muy_corto": "❌ Prompt muy corto", | |
| "sin_estilo": "🎨 Falta especificar estilo artístico", | |
| "sin_calidad": "✨ Faltan modificadores de calidad", | |
| "sin_iluminacion": "💡 No se describe la iluminación", | |
| "sin_composicion": "📷 Falta información de composición/encuadre", | |
| "palabras_vagas": "📝 Contiene palabras demasiado vagas" | |
| } | |
| issues_text = "\n".join([issue_names.get(i, i) for i in analysis["issues"]]) | |
| else: | |
| issues_text = "✅ No se detectaron problemas" | |
| suggestions_text = '\n'.join(analysis['suggestions']) if analysis['suggestions'] else '¡El prompt está bien estructurado!' | |
| report = f"""## 📊 Análisis Detallado | |
| ### Calificación: {grade} ({score}/100) | |
| --- | |
| ### 📈 Estadísticas | |
| | Métrica | Valor | | |
| |---------|-------| | |
| | Palabras | {analysis['word_count']} | | |
| | Caracteres | {analysis['char_count']} | | |
| --- | |
| ### 🔍 Problemas Detectados | |
| {issues_text} | |
| --- | |
| ### 💡 Sugerencias de Mejora | |
| {suggestions_text} | |
| --- | |
| ### 📚 Tips Generales | |
| - Los prompts más efectivos tienen entre 15-40 palabras | |
| - Incluye siempre el estilo visual deseado | |
| - Especifica la iluminación para mayor control | |
| - Usa modificadores de calidad al inicio del prompt | |
| - Evita palabras genéricas como "bonito" o "bueno" | |
| """ | |
| return report | |
| def get_style_examples(style: str) -> str: | |
| """Muestra ejemplos para un estilo específico""" | |
| if not style or style == "Ninguno": | |
| return "Selecciona un estilo para ver ejemplos" | |
| examples = { | |
| "Fotorealista": ( | |
| "**Ejemplos de prompts fotorealistas:**\n\n" | |
| "1. `professional photograph of a woman, natural lighting, 85mm lens, shallow depth of field, photorealistic, 8k uhd`\n\n" | |
| "2. `hyperrealistic photo of a mountain landscape, golden hour, dramatic clouds, raw photo, high dynamic range`\n\n" | |
| "3. `product photography of a luxury watch, studio lighting, macro shot, commercial photography, pristine details`" | |
| ), | |
| "Anime": ( | |
| "**Ejemplos de prompts anime:**\n\n" | |
| "1. `anime girl with blue hair, cherry blossom background, studio ghibli style, vibrant colors, detailed eyes, key visual`\n\n" | |
| "2. `epic anime battle scene, dynamic action pose, energy effects, dramatic lighting, anime key visual, trending on pixiv`\n\n" | |
| "3. `cozy anime room interior, warm lighting, detailed background, slice of life aesthetic, makoto shinkai style`" | |
| ), | |
| "Arte Digital": ( | |
| "**Ejemplos de arte digital:**\n\n" | |
| "1. `digital painting of a fantasy castle, dramatic sky, concept art, artstation trending, highly detailed, epic composition`\n\n" | |
| "2. `character design, full body portrait, detailed armor, digital art, fantasy warrior, professional illustration`\n\n" | |
| "3. `environment concept art, alien planet, sci-fi landscape, matte painting, cinematic, artstation winner`" | |
| ), | |
| "Pintura": ( | |
| "**Ejemplos de pintura:**\n\n" | |
| "1. `oil painting of a serene lake, impressionist style, visible brush strokes, golden hour lighting, museum quality`\n\n" | |
| "2. `renaissance portrait, classical technique, dramatic chiaroscuro, oil on canvas, by old masters`\n\n" | |
| "3. `watercolor landscape, soft edges, wet on wet technique, delicate colors, paper texture visible`" | |
| ), | |
| "3D": ( | |
| "**Ejemplos de 3D/CGI:**\n\n" | |
| "1. `3D render of a cute robot character, octane render, subsurface scattering, studio lighting, pixar style`\n\n" | |
| "2. `architectural visualization, modern house, ray tracing, unreal engine 5, photorealistic materials`\n\n" | |
| "3. `3D character model, fantasy creature, zbrush detail, substance painter textures, turntable view`" | |
| ), | |
| "Cinematico": ( | |
| "**Ejemplos cinematográficos:**\n\n" | |
| "1. `cinematic still from a sci-fi movie, anamorphic lens, dramatic lighting, movie poster composition, 4k`\n\n" | |
| "2. `film noir scene, high contrast, dramatic shadows, mysterious atmosphere, classic hollywood style`\n\n" | |
| "3. `epic movie landscape, sweeping vista, volumetric fog, golden hour, widescreen composition`" | |
| ) | |
| } | |
| return examples.get(style, "No hay ejemplos disponibles para este estilo") | |
| # ===== TEXTOS LARGOS ===== | |
| GUIDE_TEXT = """## 📖 Guía Rápida de Prompts | |
| ### Estructura recomendada: [Calidad] + [Sujeto principal] + [Estilo] + [Detalles] + [Iluminación] + [Composición] | |
| ### Ejemplo práctico: masterpiece, best quality, a beautiful elven princess with silver hair, | |
| fantasy art style, intricate jewelry, magical forest background, | |
| ethereal lighting, portrait shot, highly detailed | |
| --- | |
| ### ⚡ Diferencias entre modelos: | |
| | Modelo | Tokens | Pesos | Estilo de prompt | | |
| |--------|--------|-------|------------------| | |
| | SD 1.5 | 77 | ✅ (word:1.2) | Tags separados por comas | | |
| | SDXL | 77 | ✅ (word:1.2) | Similar a SD, más natural | | |
| | FLUX | 256 | ❌ | Descripciones naturales | | |
| | Midjourney | 500 | ✅ ::peso | Natural + parámetros | | |
| | DALL-E 3 | 4000 | ❌ | Oraciones descriptivas | | |
| --- | |
| ### 🎯 Palabras clave por categoría: | |
| **Calidad:** masterpiece, best quality, highly detailed, 8k, uhd, professional | |
| **Iluminación:** dramatic lighting, soft light, golden hour, studio lighting, rim light | |
| **Composición:** portrait, full body, close-up, wide shot, bird's eye view | |
| **Estilos:** oil painting, digital art, photograph, 3d render, watercolor, sketch | |
| """ | |
| TIPS_TEXT = """### 💡 Tips para cada componente: | |
| - **Sujeto**: Sé específico. "young woman with curly red hair" > "woman" | |
| - **Estilo**: Define la estética visual del resultado | |
| - **Iluminación**: Afecta dramáticamente el mood de la imagen | |
| - **Ambiente**: Establece el tono emocional | |
| - **Encuadre**: Controla la composición de la imagen | |
| """ | |
| FOOTER_TEXT = """--- | |
| <div style="text-align: center;"> | |
| <strong>Prompt Enhancer Pro</strong> | Creado para la comunidad de generación de imágenes con IA<br> | |
| Compatible con: Stable Diffusion, SDXL, FLUX, Midjourney y DALL-E 3 | |
| </div> | |
| """ | |
| HEADER_HTML = """ | |
| <div style="text-align: center; margin-bottom: 1.5em;"> | |
| <h1 style="color: #2563eb; margin-bottom: 0.3em;">🎨 Prompt Enhancer Pro</h1> | |
| <p style="color: #6b7280; font-size: 1.1em;">Mejora y optimiza tus prompts para generación de imágenes con IA</p> | |
| </div> | |
| """ | |
| # ===== INTERFAZ GRADIO 6.0+ ===== | |
| def create_app(): | |
| """Crea la aplicación Gradio""" | |
| with gr.Blocks(title="Prompt Enhancer Pro") as app: | |
| gr.HTML(HEADER_HTML) | |
| with gr.Tabs(): | |
| # ===== TAB 1: MEJORAR PROMPT ===== | |
| with gr.TabItem("✨ Mejorar Prompt"): | |
| gr.Markdown("### Transforma tu prompt simple en uno profesional") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| input_prompt = gr.Textbox( | |
| label="Tu prompt original", | |
| placeholder="Escribe tu prompt aquí... (puede ser en español o inglés)", | |
| lines=3 | |
| ) | |
| with gr.Row(): | |
| model_select = gr.Dropdown( | |
| choices=["Stable Diffusion 1.5", "Stable Diffusion XL", | |
| "FLUX.1", "Midjourney", "DALL-E 3"], | |
| value="Stable Diffusion XL", | |
| label="Modelo destino" | |
| ) | |
| style_select = gr.Dropdown( | |
| choices=["Ninguno", "Fotorealista", "Anime", "Arte Digital", | |
| "Pintura", "3D", "Cinematico", "Minimalista", "Fantasia"], | |
| value="Ninguno", | |
| label="Estilo artístico" | |
| ) | |
| with gr.Row(): | |
| add_quality = gr.Checkbox(label="Añadir tokens de calidad", value=True) | |
| add_negative = gr.Checkbox(label="Generar negative prompt", value=True) | |
| enhance_btn = gr.Button("🚀 Mejorar Prompt", variant="primary") | |
| with gr.Column(scale=1): | |
| output_prompt = gr.Textbox( | |
| label="✅ Prompt mejorado", | |
| lines=4, | |
| interactive=False | |
| ) | |
| output_negative = gr.Textbox( | |
| label="❌ Negative prompt", | |
| lines=2, | |
| interactive=False | |
| ) | |
| model_info = gr.Markdown("") | |
| with gr.Row(): | |
| with gr.Column(): | |
| analysis_output = gr.Markdown(label="Análisis") | |
| with gr.Column(): | |
| variations_output = gr.Markdown(label="Variaciones sugeridas") | |
| enhance_btn.click( | |
| fn=enhance_prompt, | |
| inputs=[input_prompt, model_select, style_select, add_quality, add_negative], | |
| outputs=[output_prompt, output_negative, analysis_output, variations_output, model_info] | |
| ) | |
| # ===== TAB 2: CORRECTOR ===== | |
| with gr.TabItem("🔧 Corrector de Errores"): | |
| gr.Markdown("### Detecta y corrige errores comunes en tus prompts") | |
| with gr.Row(): | |
| with gr.Column(): | |
| fix_input = gr.Textbox( | |
| label="Prompt con posibles errores", | |
| placeholder="Pega aquí un prompt que quieras revisar...", | |
| lines=4 | |
| ) | |
| fix_btn = gr.Button("🔍 Analizar y Corregir", variant="primary") | |
| with gr.Column(): | |
| fix_output = gr.Textbox( | |
| label="Prompt corregido", | |
| lines=4, | |
| interactive=False | |
| ) | |
| fixes_log = gr.Markdown("") | |
| fix_btn.click( | |
| fn=fix_prompt, | |
| inputs=[fix_input], | |
| outputs=[fix_output, fixes_log] | |
| ) | |
| # ===== TAB 3: CONSTRUCTOR ===== | |
| with gr.TabItem("🏗️ Constructor de Prompts"): | |
| gr.Markdown("### Construye un prompt paso a paso") | |
| with gr.Row(): | |
| with gr.Column(): | |
| build_subject = gr.Textbox( | |
| label="Sujeto principal *", | |
| placeholder="Ej: a young woman with red hair, a futuristic city..." | |
| ) | |
| with gr.Row(): | |
| build_style = gr.Dropdown( | |
| choices=["Ninguno", "Clasico", "Impresionista", "Surrealista", | |
| "Pop Art", "Art Nouveau", "Concept Art", "Anime", | |
| "Fantasia", "Sci-fi", "Horror"], | |
| value="Ninguno", | |
| label="Estilo artístico" | |
| ) | |
| build_lighting = gr.Dropdown( | |
| choices=["Ninguno", "Dramatica", "Suave", "Natural", | |
| "Estudio", "Neon", "Cinematica"], | |
| value="Ninguno", | |
| label="Iluminación" | |
| ) | |
| with gr.Row(): | |
| build_mood = gr.Dropdown( | |
| choices=["Ninguno", "Oscuro", "Alegre", "Melancolico", | |
| "Epico", "Sereno", "Intenso"], | |
| value="Ninguno", | |
| label="Ambiente/Mood" | |
| ) | |
| build_camera = gr.Dropdown( | |
| choices=["Ninguno", "Cercano", "Lejano", "Retrato", | |
| "Aereo", "Bajo", "Alto"], | |
| value="Ninguno", | |
| label="Ángulo/Encuadre" | |
| ) | |
| build_quality = gr.CheckboxGroup( | |
| choices=["Alta definición (8K)", "Muy detallado", "Masterpiece", | |
| "Fotografía profesional", "Arte de alta calidad"], | |
| label="Calidad" | |
| ) | |
| build_extra = gr.Textbox( | |
| label="Detalles adicionales", | |
| placeholder="Añade cualquier detalle extra..." | |
| ) | |
| build_btn = gr.Button("🔨 Construir Prompt", variant="primary") | |
| with gr.Column(): | |
| build_output = gr.Textbox( | |
| label="Prompt construido", | |
| lines=6, | |
| interactive=False | |
| ) | |
| gr.Markdown(TIPS_TEXT) | |
| build_btn.click( | |
| fn=build_prompt, | |
| inputs=[build_subject, build_style, build_lighting, build_mood, | |
| build_camera, build_quality, build_extra], | |
| outputs=[build_output] | |
| ) | |
| # ===== TAB 4: ANALIZADOR ===== | |
| with gr.TabItem("📊 Analizador"): | |
| gr.Markdown("### Analiza la calidad y estructura de tu prompt") | |
| with gr.Row(): | |
| with gr.Column(): | |
| analyze_input = gr.Textbox( | |
| label="Prompt a analizar", | |
| placeholder="Pega cualquier prompt para obtener un análisis detallado...", | |
| lines=4 | |
| ) | |
| analyze_btn = gr.Button("📊 Analizar", variant="primary") | |
| with gr.Column(): | |
| analyze_output = gr.Markdown("") | |
| analyze_btn.click( | |
| fn=analyze_only, | |
| inputs=[analyze_input], | |
| outputs=[analyze_output] | |
| ) | |
| # ===== TAB 5: EJEMPLOS Y GUÍA ===== | |
| with gr.TabItem("📚 Guía y Ejemplos"): | |
| gr.Markdown("### Aprende a crear mejores prompts") | |
| with gr.Row(): | |
| with gr.Column(): | |
| example_style = gr.Dropdown( | |
| choices=["Fotorealista", "Anime", "Arte Digital", | |
| "Pintura", "3D", "Cinematico"], | |
| value="Fotorealista", | |
| label="Selecciona un estilo" | |
| ) | |
| show_examples_btn = gr.Button("Ver ejemplos", variant="secondary") | |
| with gr.Column(): | |
| examples_output = gr.Markdown("") | |
| show_examples_btn.click( | |
| fn=get_style_examples, | |
| inputs=[example_style], | |
| outputs=[examples_output] | |
| ) | |
| gr.Markdown("---") | |
| gr.Markdown(GUIDE_TEXT) | |
| # Footer | |
| gr.Markdown(FOOTER_TEXT) | |
| return app | |
| # Crear y lanzar la aplicación | |
| app = create_app() | |
| if __name__ == "__main__": | |
| app.launch() |