File size: 8,120 Bytes
876015b
ea5bac5
74e68b0
 
 
876015b
ea5bac5
876015b
ea5bac5
 
876015b
ea5bac5
 
 
 
 
876015b
ea5bac5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876015b
 
ea5bac5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876015b
ea5bac5
 
 
876015b
ea5bac5
 
 
 
 
 
 
 
876015b
 
ea5bac5
 
876015b
74e68b0
ea5bac5
 
 
 
876015b
 
 
ea5bac5
 
 
876015b
ea5bac5
 
876015b
ea5bac5
 
 
 
 
876015b
 
 
ea5bac5
 
 
 
 
 
 
876015b
ea5bac5
 
876015b
ea5bac5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
876015b
 
ea5bac5
 
 
 
 
 
 
 
 
 
 
 
876015b
 
ea5bac5
 
876015b
ea5bac5
74e68b0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import random
import gradio as gr
from data import fashion_elements, PhotoReal

negative_prompt_fusion = "blurry, deformed, ugly, mutilated, disfigured, extra limbs, extra fingers, poorly drawn hands, poorly drawn feet, mutated hands, mutation, deformed, bad anatomy, bad proportions, extra arms, extra legs, fused fingers, too many fingers, long neck, username, watermark, signature, overexposed, underexposed, bad lighting, distorted face, low quality, artifacts"

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(css=custom_css) 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)