Dan Bochman commited on
Commit
c433f12
·
1 Parent(s): e727ae9

feat(ui): add 3-column layout with smart garment gallery

Browse files

Reorganize 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.

Files changed (3) hide show
  1. .gitignore +1 -1
  2. app.py +52 -21
  3. 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
- garment_only_examples = [os.path.join(examples_dir, "garment0.png")]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- # Left column: Inputs
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="Garment Category",
221
  )
222
  garment_photo_type = gr.Dropdown(
223
  choices=GARMENT_PHOTO_TYPES,
224
  value="model",
225
- label="Garment Photo Type",
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 handler
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

  • SHA256: 968d7dd2fff92d11bd5595ccaeabc56eabb3bc1de51994605f30925e0e02c62f
  • Pointer size: 131 Bytes
  • Size of remote file: 140 kB