import random import gradio as gr from data import fashion_elements, PhotoReal, negative_prompt_fusion class FashionPromptGenerator: def __init__(self): self.previous_prompts = set() self.photo_real = PhotoReal() def generate_unique_prompts(self, subject_name, num_prompts=5): """Genera una lista de prompts únicos.""" if not subject_name or subject_name.isspace(): subject_name = "a beautiful woman" prompts = [] max_attempts = num_prompts * 10 attempts = 0 while len(prompts) < num_prompts and attempts < max_attempts: prompt = self._build_fused_prompt(subject_name) prompt_hash = hash(prompt) if prompt_hash not in self.previous_prompts: self.previous_prompts.add(prompt_hash) prompts.append(prompt) attempts += 1 # Si no se logran suficientes prompts únicos, rellena con algunos aleatorios (aunque se repitan) while len(prompts) < num_prompts: prompts.append(self._build_fused_prompt(subject_name)) return prompts def _build_fused_prompt(self, subject_name): """Construye un prompt fusionando los estilos photorealistic y voyeuristic.""" # --- Elementos de Photorealistic --- role = random.choice(self.photo_real.ROLES) body = random.choice(self.photo_real.BODY) skin = random.choice(self.photo_real.SKIN) hair = random.choice(self.photo_real.HAIR) expression = random.choice(self.photo_real.EXPRESSION) sensual_pose = random.choice(self.photo_real.SENSUAL_POSES) # --- Elementos de Voyeuristic --- primary_color = random.choice(fashion_elements["colors"]) discovery_moment = random.choice(fashion_elements["discovery_moments"]) reveal_action = random.choice(fashion_elements["lingerie_reveal_actions"]) background = random.choice(fashion_elements["backgrounds"]) lighting = random.choice(fashion_elements["lighting"]) # --- Construcción del Prompt --- prompt = ( f"Photorealistic portrait of {subject_name} as a {role['role']}, " f"captured from an extreme low angle, floor-level perspective, shooting upward. " f"The composition focuses on a moment of discovery, {discovery_moment}. " f"She is {reveal_action}, creating a natural and unposed exposure.\n\n" f"**Body & Appearance:**\n" f"- **Physique:** {body} with {skin}.\n" f"- **Hair:** {hair}.\n" f"- **Expression:** {expression}.\n" f"- **Outfit:** She wears {role['outfit']} over {primary_color} lingerie. " f"Complemented by {self.photo_real.STOCKINGS} and {self.photo_real.HEELS}.\n\n" f"**Scene & Atmosphere:**\n" f"- **Setting:** {background} with {lighting}.\n" f"- **Pose:** {sensual_pose['pose']} ({sensual_pose['view']} view), emphasizing a sensual and captivating stance.\n" f"- **Mood:** Intimate, sensual, and elegantly composed.\n\n" f"**Technical Details:**\n" f"- **Camera:** {self.photo_real.CAMERA}.\n" f"- **Quality:** Ultra HD, professional retouching, sharp focus on intimate details and facial expression.\n\n" f"The image captures a fleeting, intimate moment that feels both spontaneous and beautifully composed, emphasizing the sensual discovery of hidden lingerie through natural movement and expert framing. " f"--ar 9:16 --v 6 --q 2 --style raw --stylize 100" ) return prompt.strip() def clear_history(self): """Limpia el historial de prompts generados.""" self.previous_prompts.clear() custom_css = """ .prompt-box { border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; margin-bottom: 16px; background-color: #f8fafc; font-family: 'Monaco', 'Consolas', monospace; font-size: 0.9em; } .prompt-title { font-weight: bold; margin-bottom: 8px; color: #4a5568; } .header { text-align: center; margin-bottom: 20px; } """ def create_gradio_interface(): generator = FashionPromptGenerator() with gr.Blocks() as demo: gr.Markdown(""" # 🎭 Advanced Fashion Prompt Generator *Create photorealistic, discovery-focused prompts with a single, powerful style.* """, elem_classes="header") with gr.Row(): with gr.Column(scale=2): celebrity_input = gr.Textbox( label="Celebrity Name (Optional)", placeholder="Enter a name or leave blank for 'a beautiful woman'", ) num_prompts_slider = gr.Slider( minimum=1, maximum=10, value=5, step=1, label="Number of Prompts to Generate" ) with gr.Column(scale=1): generate_btn = gr.Button("✨ Generate Prompts", variant="primary") clear_btn = gr.Button("🗑️ Clear History", variant="secondary") gr.Markdown("---") with gr.Row(): with gr.Column(): gr.Markdown("### negativo Prompt") negative_prompt_output = gr.Textbox( value=negative_prompt_fusion, label="", lines=4, interactive=False, elem_classes="prompt-box" ) gr.Markdown("## Generated Prompts") output_columns = [] output_prompts = [] for i in range(10): with gr.Column(visible=False) as col: gr.Markdown(f"### 🎯 Prompt {i+1}", elem_classes="prompt-title") prompt_output = gr.Textbox( label="", lines=10, interactive=False, elem_classes="prompt-box" ) output_columns.append(col) output_prompts.append(prompt_output) def generate_and_display(celebrity_name, num_prompts): num_prompts = int(num_prompts) prompts = generator.generate_unique_prompts(celebrity_name, num_prompts) updates = [] # Create a flat list of updates for all components for i in range(10): if i < num_prompts: # Make column visible and set textbox value updates.append(gr.update(visible=True)) updates.append(gr.update(value=prompts[i])) else: # Hide column and clear textbox value updates.append(gr.update(visible=False)) updates.append(gr.update(value="")) return updates # The outputs list needs to be flattened flat_outputs = [component for pair in zip(output_columns, output_prompts) for component in pair] generate_btn.click( fn=generate_and_display, inputs=[celebrity_input, num_prompts_slider], outputs=flat_outputs ) def clear_history_and_outputs(): generator.clear_history() updates = [] for i in range(10): updates.append(gr.update(visible=False)) # Hide column updates.append(gr.update(value="")) # Clear textbox return updates clear_btn.click( fn=clear_history_and_outputs, inputs=None, outputs=flat_outputs ) return demo if __name__ == "__main__": demo = create_gradio_interface() demo.launch(share=True, css=custom_css)