Spaces:
Running on Zero
Running on Zero
Prompt Builder: รูปร่าง/สัดส่วน -> multiselect dropdown of model-reliable body tags (Thai label, English value) + free text; _field() handles list values
Browse files
app.py
CHANGED
|
@@ -166,27 +166,39 @@ def reload_registry():
|
|
| 166 |
)
|
| 167 |
|
| 168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
def build_prompt(subject, age, ethnicity, skin, face, body, hair, eyes, outfit, pose,
|
| 170 |
expression, scene, lighting, shot):
|
| 171 |
"""Assemble form fields into a prompt. Thai values are fine — the auto-translator
|
| 172 |
-
turns the whole thing into English at generate time.
|
|
|
|
| 173 |
parts = []
|
| 174 |
# Framing/shot goes FIRST so "full body / head to toe" survives CLIP's 77-token cut
|
| 175 |
# (it's the key compositional cue; if truncated, SD1.5 defaults to a portrait crop).
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
| 180 |
-
|
| 181 |
-
if
|
| 182 |
-
who = f"{
|
|
|
|
|
|
|
| 183 |
parts.append(who)
|
| 184 |
# Priority order for CLIP's 77-token budget: compositional anchors first
|
| 185 |
# (location/lighting/outfit/pose), fine appearance details last (least harmful
|
| 186 |
# if truncated). Skin texture realism is carried by the model's style_prefix anyway.
|
| 187 |
for v in (scene, lighting, outfit, pose, expression, body, hair, skin, face, eyes):
|
| 188 |
-
|
| 189 |
-
|
|
|
|
| 190 |
thai = ", ".join(parts)
|
| 191 |
# Photographic suffix (NOT "masterpiece/best quality" — those art tokens push the model
|
| 192 |
# toward an illustrated/CG look. The model's style_prefix + negative do the heavy lifting).
|
|
@@ -223,7 +235,24 @@ with gr.Blocks(css=CSS, theme=gr.themes.Soft(primary_hue="blue"),
|
|
| 223 |
b_age = gr.Textbox(label="อายุ", placeholder="เช่น 25")
|
| 224 |
b_ethnicity = gr.Textbox(label="เชื้อชาติ / สัญชาติ", placeholder="เช่น เกาหลี, ไทย")
|
| 225 |
with gr.Row():
|
| 226 |
-
b_body = gr.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 227 |
b_hair = gr.Textbox(label="ทรงผม / สีผม", placeholder="เช่น ผมยาวสีดำ, ผมบลอนด์")
|
| 228 |
b_eyes = gr.Textbox(label="สีตา", placeholder="เช่น ตาสีน้ำตาล")
|
| 229 |
with gr.Row():
|
|
|
|
| 166 |
)
|
| 167 |
|
| 168 |
|
| 169 |
+
def _field(v):
|
| 170 |
+
"""Normalise a Prompt Builder field to a clean string. Dropdowns with
|
| 171 |
+
multiselect return a list — join those; plain Textboxes return a string."""
|
| 172 |
+
if isinstance(v, (list, tuple)):
|
| 173 |
+
return ", ".join(str(x).strip() for x in v if x and str(x).strip())
|
| 174 |
+
return str(v).strip() if v is not None else ""
|
| 175 |
+
|
| 176 |
+
|
| 177 |
def build_prompt(subject, age, ethnicity, skin, face, body, hair, eyes, outfit, pose,
|
| 178 |
expression, scene, lighting, shot):
|
| 179 |
"""Assemble form fields into a prompt. Thai values are fine — the auto-translator
|
| 180 |
+
turns the whole thing into English at generate time. Dropdown fields already carry
|
| 181 |
+
model-friendly English tags (e.g. 'hourglass figure')."""
|
| 182 |
parts = []
|
| 183 |
# Framing/shot goes FIRST so "full body / head to toe" survives CLIP's 77-token cut
|
| 184 |
# (it's the key compositional cue; if truncated, SD1.5 defaults to a portrait crop).
|
| 185 |
+
shot = _field(shot)
|
| 186 |
+
if shot:
|
| 187 |
+
parts.append(shot)
|
| 188 |
+
who = _field(subject) or "ผู้หญิง"
|
| 189 |
+
ethnicity, age = _field(ethnicity), _field(age)
|
| 190 |
+
if ethnicity:
|
| 191 |
+
who = f"{ethnicity} {who}"
|
| 192 |
+
if age:
|
| 193 |
+
who = f"{who} อายุ {age} ปี"
|
| 194 |
parts.append(who)
|
| 195 |
# Priority order for CLIP's 77-token budget: compositional anchors first
|
| 196 |
# (location/lighting/outfit/pose), fine appearance details last (least harmful
|
| 197 |
# if truncated). Skin texture realism is carried by the model's style_prefix anyway.
|
| 198 |
for v in (scene, lighting, outfit, pose, expression, body, hair, skin, face, eyes):
|
| 199 |
+
s = _field(v)
|
| 200 |
+
if s:
|
| 201 |
+
parts.append(s)
|
| 202 |
thai = ", ".join(parts)
|
| 203 |
# Photographic suffix (NOT "masterpiece/best quality" — those art tokens push the model
|
| 204 |
# toward an illustrated/CG look. The model's style_prefix + negative do the heavy lifting).
|
|
|
|
| 235 |
b_age = gr.Textbox(label="อายุ", placeholder="เช่น 25")
|
| 236 |
b_ethnicity = gr.Textbox(label="เชื้อชาติ / สัญชาติ", placeholder="เช่น เกาหลี, ไทย")
|
| 237 |
with gr.Row():
|
| 238 |
+
b_body = gr.Dropdown(
|
| 239 |
+
label="รูปร่าง / สัดส่วน (เลือกได้หลายอัน · พิมพ์เองได้)",
|
| 240 |
+
choices=[
|
| 241 |
+
("ผอมเพรียว / slim", "slim, slender figure"),
|
| 242 |
+
("ตัวเล็กบอบบาง / petite", "petite, small frame"),
|
| 243 |
+
("ทรงนาฬิกาทราย / hourglass", "hourglass figure, narrow waist"),
|
| 244 |
+
("อวบอั๋นเว้าโค้ง / curvy", "curvy, voluptuous"),
|
| 245 |
+
("ฟิตมีกล้าม / athletic", "athletic, toned, fit body"),
|
| 246 |
+
("อึ๋มอกใหญ่ / busty", "busty, large breasts"),
|
| 247 |
+
("ท้วมอวบ / chubby", "chubby, plump"),
|
| 248 |
+
("สูงขายาวทรงนางแบบ / tall model", "tall, long legs, model body"),
|
| 249 |
+
("สะโพกผาย / wide hips", "wide hips"),
|
| 250 |
+
("ต้นขาหนา / thick thighs", "thick thighs"),
|
| 251 |
+
("เอวเล็ก / slim waist", "slim waist"),
|
| 252 |
+
("อกเล็ก / small breasts", "small breasts"),
|
| 253 |
+
("ทรงผู้ใหญ่ / mature", "mature body"),
|
| 254 |
+
],
|
| 255 |
+
value=None, multiselect=True, allow_custom_value=True)
|
| 256 |
b_hair = gr.Textbox(label="ทรงผม / สีผม", placeholder="เช่น ผมยาวสีดำ, ผมบลอนด์")
|
| 257 |
b_eyes = gr.Textbox(label="สีตา", placeholder="เช่น ตาสีน้ำตาล")
|
| 258 |
with gr.Row():
|