BATUTO-ART's picture
Update app.py
ea5bac5 verified
raw
history blame
7.76 kB
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)