Spaces:
Runtime error
Runtime error
Dan Bochman commited on
Commit ·
c433f12
1
Parent(s): e727ae9
feat(ui): add 3-column layout with smart garment gallery
Browse filesReorganize demo UI from 2 columns to 3 columns:
- Column 1: Person image and examples
- Column 2: Garment image, category/photo type dropdowns, garment gallery
- Column 3: Result image, run button, advanced settings
Replace gr.Examples with gr.Gallery for garment examples to enable
auto-updating dropdowns when clicking a garment thumbnail. Each
example maps to its correct category and photo type settings.
User uploads no longer affect dropdown values - only gallery clicks
trigger the auto-update behavior.
- .gitignore +1 -1
- app.py +52 -21
- assets/examples/garment7.jpg +3 -0
.gitignore
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
# Virtual environment
|
| 2 |
-
.venv/
|
| 3 |
venv/
|
| 4 |
env/
|
| 5 |
|
|
|
|
| 1 |
# Virtual environment
|
| 2 |
+
.venv*/
|
| 3 |
venv/
|
| 4 |
env/
|
| 5 |
|
app.py
CHANGED
|
@@ -174,7 +174,24 @@ paired_examples = [
|
|
| 174 |
|
| 175 |
# Individual examples (classic from repo)
|
| 176 |
person_only_examples = [os.path.join(examples_dir, "person0.png")]
|
| 177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
# Build UI
|
| 180 |
with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
@@ -183,7 +200,7 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 183 |
gr.HTML(tips_html)
|
| 184 |
|
| 185 |
with gr.Row(equal_height=False):
|
| 186 |
-
#
|
| 187 |
with gr.Column(scale=1):
|
| 188 |
person_image = gr.Image(
|
| 189 |
label="Person Image",
|
|
@@ -199,6 +216,8 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 199 |
label="Person Examples",
|
| 200 |
)
|
| 201 |
|
|
|
|
|
|
|
| 202 |
garment_image = gr.Image(
|
| 203 |
label="Garment Image",
|
| 204 |
type="pil",
|
|
@@ -206,25 +225,39 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 206 |
elem_classes=["contain"],
|
| 207 |
)
|
| 208 |
|
| 209 |
-
# Individual garment examples
|
| 210 |
-
gr.Examples(
|
| 211 |
-
examples=garment_only_examples,
|
| 212 |
-
inputs=garment_image,
|
| 213 |
-
label="Garment Examples",
|
| 214 |
-
)
|
| 215 |
-
|
| 216 |
with gr.Row():
|
| 217 |
category = gr.Dropdown(
|
| 218 |
choices=CATEGORIES,
|
| 219 |
value="tops",
|
| 220 |
-
label="
|
| 221 |
)
|
| 222 |
garment_photo_type = gr.Dropdown(
|
| 223 |
choices=GARMENT_PHOTO_TYPES,
|
| 224 |
value="model",
|
| 225 |
-
label="
|
| 226 |
)
|
| 227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
run_button = gr.Button("Try On", variant="primary", size="lg")
|
| 229 |
|
| 230 |
# Advanced settings
|
|
@@ -257,15 +290,6 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 257 |
info="Preserves body features and allows unconstrained garment volume. Disable for tighter garment fitting.",
|
| 258 |
)
|
| 259 |
|
| 260 |
-
# Right column: Output
|
| 261 |
-
with gr.Column(scale=1):
|
| 262 |
-
result_image = gr.Image(
|
| 263 |
-
label="Try-On Result",
|
| 264 |
-
type="pil",
|
| 265 |
-
interactive=False,
|
| 266 |
-
elem_classes=["contain"],
|
| 267 |
-
)
|
| 268 |
-
|
| 269 |
# Paired examples at the bottom
|
| 270 |
gr.Examples(
|
| 271 |
examples=paired_examples,
|
|
@@ -273,7 +297,7 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 273 |
label="Complete Examples (click to load person + garment + settings)",
|
| 274 |
)
|
| 275 |
|
| 276 |
-
# Event
|
| 277 |
run_button.click(
|
| 278 |
fn=try_on,
|
| 279 |
inputs=[
|
|
@@ -289,6 +313,13 @@ with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
| 289 |
outputs=[result_image],
|
| 290 |
)
|
| 291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
# Configure queue with concurrency limit to prevent GPU OOM
|
| 293 |
demo.queue(default_concurrency_limit=1, max_size=30)
|
| 294 |
|
|
|
|
| 174 |
|
| 175 |
# Individual examples (classic from repo)
|
| 176 |
person_only_examples = [os.path.join(examples_dir, "person0.png")]
|
| 177 |
+
|
| 178 |
+
# Garment examples with their settings: (image_path, category, photo_type)
|
| 179 |
+
# Order matters - index in Gallery corresponds to this list
|
| 180 |
+
garment_examples_data = [
|
| 181 |
+
(os.path.join(examples_dir, "garment0.png"), "tops", "model"),
|
| 182 |
+
(os.path.join(examples_dir, "garment7.jpg"), "tops", "flat-lay"),
|
| 183 |
+
]
|
| 184 |
+
garment_gallery_images = [item[0] for item in garment_examples_data]
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
def on_garment_gallery_select(evt: gr.SelectData):
|
| 188 |
+
"""Handle garment gallery selection - load image and update dropdowns."""
|
| 189 |
+
idx = evt.index
|
| 190 |
+
if idx < len(garment_examples_data):
|
| 191 |
+
image_path, cat, photo_type = garment_examples_data[idx]
|
| 192 |
+
return Image.open(image_path), cat, photo_type
|
| 193 |
+
return None, "tops", "model"
|
| 194 |
+
|
| 195 |
|
| 196 |
# Build UI
|
| 197 |
with gr.Blocks(css=CUSTOM_CSS) as demo:
|
|
|
|
| 200 |
gr.HTML(tips_html)
|
| 201 |
|
| 202 |
with gr.Row(equal_height=False):
|
| 203 |
+
# Column 1: Person
|
| 204 |
with gr.Column(scale=1):
|
| 205 |
person_image = gr.Image(
|
| 206 |
label="Person Image",
|
|
|
|
| 216 |
label="Person Examples",
|
| 217 |
)
|
| 218 |
|
| 219 |
+
# Column 2: Garment
|
| 220 |
+
with gr.Column(scale=1):
|
| 221 |
garment_image = gr.Image(
|
| 222 |
label="Garment Image",
|
| 223 |
type="pil",
|
|
|
|
| 225 |
elem_classes=["contain"],
|
| 226 |
)
|
| 227 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
with gr.Row():
|
| 229 |
category = gr.Dropdown(
|
| 230 |
choices=CATEGORIES,
|
| 231 |
value="tops",
|
| 232 |
+
label="Category",
|
| 233 |
)
|
| 234 |
garment_photo_type = gr.Dropdown(
|
| 235 |
choices=GARMENT_PHOTO_TYPES,
|
| 236 |
value="model",
|
| 237 |
+
label="Photo Type",
|
| 238 |
)
|
| 239 |
|
| 240 |
+
# Garment examples as clickable gallery
|
| 241 |
+
gr.Markdown("**Garment Examples** (click to load with settings)")
|
| 242 |
+
garment_gallery = gr.Gallery(
|
| 243 |
+
value=garment_gallery_images,
|
| 244 |
+
columns=2,
|
| 245 |
+
rows=1,
|
| 246 |
+
height="auto",
|
| 247 |
+
object_fit="contain",
|
| 248 |
+
show_label=False,
|
| 249 |
+
allow_preview=False,
|
| 250 |
+
)
|
| 251 |
+
|
| 252 |
+
# Column 3: Result
|
| 253 |
+
with gr.Column(scale=1):
|
| 254 |
+
result_image = gr.Image(
|
| 255 |
+
label="Try-On Result",
|
| 256 |
+
type="pil",
|
| 257 |
+
interactive=False,
|
| 258 |
+
elem_classes=["contain"],
|
| 259 |
+
)
|
| 260 |
+
|
| 261 |
run_button = gr.Button("Try On", variant="primary", size="lg")
|
| 262 |
|
| 263 |
# Advanced settings
|
|
|
|
| 290 |
info="Preserves body features and allows unconstrained garment volume. Disable for tighter garment fitting.",
|
| 291 |
)
|
| 292 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 293 |
# Paired examples at the bottom
|
| 294 |
gr.Examples(
|
| 295 |
examples=paired_examples,
|
|
|
|
| 297 |
label="Complete Examples (click to load person + garment + settings)",
|
| 298 |
)
|
| 299 |
|
| 300 |
+
# Event handlers
|
| 301 |
run_button.click(
|
| 302 |
fn=try_on,
|
| 303 |
inputs=[
|
|
|
|
| 313 |
outputs=[result_image],
|
| 314 |
)
|
| 315 |
|
| 316 |
+
# Garment gallery selection - loads image and updates dropdowns
|
| 317 |
+
garment_gallery.select(
|
| 318 |
+
fn=on_garment_gallery_select,
|
| 319 |
+
inputs=None,
|
| 320 |
+
outputs=[garment_image, category, garment_photo_type],
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
# Configure queue with concurrency limit to prevent GPU OOM
|
| 324 |
demo.queue(default_concurrency_limit=1, max_size=30)
|
| 325 |
|
assets/examples/garment7.jpg
ADDED
|
Git LFS Details
|