Spaces:
Sleeping
Sleeping
| 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) | |