seawolf2357 commited on
Commit
92d4811
·
verified ·
1 Parent(s): d781c9c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -414
app.py CHANGED
@@ -61,7 +61,6 @@ def create_hacked_forward(module):
61
  def lora_forward(self, active_adapter, x, *args, **kwargs):
62
  result = self.base_layer(x, *args, **kwargs)
63
  if active_adapter is not None:
64
- torch_result_dtype = result.dtype
65
  lora_A = self.lora_A[active_adapter]
66
  lora_B = self.lora_B[active_adapter]
67
  dropout = self.lora_dropout[active_adapter]
@@ -94,16 +93,12 @@ def seed_everything(seed=0):
94
 
95
  @spaces.GPU
96
  def generate(person_image, object_image, object_class, steps, guidance_scale, seed):
97
- # set seed
98
  if seed == -1:
99
  seed = random.randint(0, 2**32 - 1)
100
  seed_everything(seed)
101
 
102
- # resize model
103
  max_area = 1024 * 1024
104
- oW = person_image.width
105
- oH = person_image.height
106
-
107
  ratio = math.sqrt(max_area / (oW * oH))
108
  ratio = min(1, ratio)
109
  tW, tH = int(oW * ratio) // 16 * 16, int(oH * ratio) // 16 * 16
@@ -113,7 +108,6 @@ def generate(person_image, object_image, object_class, steps, guidance_scale, se
113
  ])
114
  person_image = transform(person_image)
115
 
116
- # resize and padding garment
117
  ratio = min(tW / object_image.width, tH / object_image.height)
118
  transform = T.Compose([
119
  T.Resize((int(object_image.height * ratio), int(object_image.width * ratio))),
@@ -126,7 +120,6 @@ def generate(person_image, object_image, object_class, steps, guidance_scale, se
126
  min_y = (tH - new_h) // 2
127
  object_image_padded[:, min_y: min_y + new_h, min_x: min_x + new_w] = object_image
128
 
129
- # prepare prompts and conditions
130
  prompts = [args.object_map[object_class]] * 2
131
  img_cond = torch.stack([person_image, object_image_padded]).to(dtype=weight_dtype, device=device)
132
  mask = torch.zeros_like(img_cond).to(img_cond)
@@ -146,448 +139,90 @@ def generate(person_image, object_image, object_class, steps, guidance_scale, se
146
  return img
147
 
148
 
149
- # Custom CSS for enhanced visual design
150
  custom_css = """
151
- /* background gradient */
152
  .gradio-container {
153
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
154
  font-family: 'Inter', sans-serif;
155
  }
156
 
157
- /* main container */
158
- .container {
159
- max-width: 1400px !important;
160
- margin: auto;
161
- padding: 20px;
162
- }
163
-
164
- /* header */
165
- #header {
166
- background: rgba(255, 255, 255, 0.1);
167
- backdrop-filter: blur(10px);
168
- border-radius: 20px;
169
- padding: 30px;
170
- margin-bottom: 30px;
171
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
172
- border: 1px solid rgba(255, 255, 255, 0.2);
173
- }
174
-
175
- #header h1 {
176
- background: linear-gradient(45deg, #fff, #e0e0ff);
177
- -webkit-background-clip: text;
178
- -webkit-text-fill-color: transparent;
179
- font-size: 3.5em;
180
- font-weight: 800;
181
- text-align: center;
182
- margin: 0;
183
- text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
184
- }
185
-
186
- #subtitle {
187
- text-align: center;
188
- color: rgba(255, 255, 255, 0.9);
189
- font-size: 1.2em;
190
- margin-top: 10px;
191
- font-weight: 300;
192
- }
193
-
194
- /* image upload cards */
195
- .image-container {
196
- background: rgba(255, 255, 255, 0.95);
197
- border-radius: 16px;
198
- padding: 20px;
199
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
200
- transition: transform 0.3s ease, box-shadow 0.3s ease;
201
- border: 2px solid rgba(102, 126, 234, 0.3);
202
- }
203
-
204
- .image-container:hover {
205
- transform: translateY(-5px);
206
- box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3);
207
- border-color: rgba(102, 126, 234, 0.6);
208
- }
209
-
210
- /* remove default placeholders entirely */
211
- .gr-image .placeholder,
212
- .gr-image .placeholder-content,
213
- .gr-image .svelte-1gfkn6j_center {
214
  display: none !important;
215
  visibility: hidden !important;
216
  }
217
-
218
- /* clean upload area */
219
- .gr-image .wrap {
220
- background: transparent !important;
221
- min-height: 400px !important;
222
  }
223
 
 
 
224
  .gr-image .upload-container {
225
- background: linear-gradient(135deg, rgba(248, 250, 252, 0.5) 0%, rgba(241, 245, 249, 0.5) 100%) !important;
226
- border: 3px dashed rgba(102, 126, 234, 0.4) !important;
227
- border-radius: 12px !important;
228
  min-height: 400px !important;
229
- position: relative !important;
230
- cursor: pointer !important;
231
- transition: all 0.3s ease !important;
232
- }
233
-
234
- .gr-image .upload-container:hover {
235
- border-color: rgba(102, 126, 234, 0.7) !important;
236
- background: linear-gradient(135deg, rgba(248, 250, 252, 0.7) 0%, rgba(241, 245, 249, 0.7) 100%) !important;
237
- }
238
-
239
- /* uploaded image styling */
240
- .gr-image img {
241
  border-radius: 12px !important;
242
- position: relative !important;
243
- z-index: 10 !important;
244
- max-width: 100% !important;
245
- height: auto !important;
246
- display: block !important;
247
- }
248
-
249
- /* when an image exists, remove any dashed border or bg and hide overlays/icons */
250
- .gr-image:has(img) .upload-container {
251
- border: none !important;
252
- background: transparent !important;
253
- }
254
-
255
- /* completely hide any placeholder, overlay, or svg when an image is present */
256
- .gr-image:has(img) .placeholder,
257
- .gr-image:has(img) .placeholder-content,
258
- .gr-image:has(img) svg,
259
- .gr-image:has(img) [class*="placeholder"],
260
- .gr-image:has(img) [class*="overlay"],
261
- .gr-image:has(img) .upload-container::after {
262
- display: none !important;
263
- visibility: hidden !important;
264
- }
265
-
266
- /* keep upload-container positioned correctly */
267
- .gr-image .upload-container {
268
  position: relative !important;
269
  }
270
-
271
- /* add friendly helper text for empty state */
 
272
  .gr-image .upload-container::after {
273
- content: "Click or Drag to Upload" !important;
274
- position: absolute !important;
275
- top: 50% !important;
276
- left: 50% !important;
277
- transform: translate(-50%, -50%) !important;
278
- color: rgba(102, 126, 234, 0.7) !important;
279
- font-size: 1.1em !important;
280
- font-weight: 500 !important;
281
- pointer-events: none !important;
282
- }
283
-
284
- /* hide helper text when an image exists */
285
- .gr-image:has(img) .upload-container::after {
286
- display: none !important;
287
- }
288
-
289
- /* labels */
290
- label {
291
- font-weight: 600 !important;
292
- color: #4a5568 !important;
293
- font-size: 1.1em !important;
294
- margin-bottom: 8px !important;
295
- display: block !important;
296
- }
297
-
298
- /* buttons */
299
  .gr-button-primary {
300
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
301
- border: none !important;
302
- color: white !important;
303
- padding: 15px 40px !important;
304
- font-size: 1.2em !important;
305
- font-weight: 600 !important;
306
- border-radius: 50px !important;
307
- cursor: pointer !important;
308
- transition: all 0.3s ease !important;
309
- box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4) !important;
310
- text-transform: uppercase !important;
311
- letter-spacing: 1px !important;
312
- }
313
-
314
- .gr-button-primary:hover {
315
- transform: translateY(-2px) !important;
316
- box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6) !important;
317
- }
318
-
319
- /* dropdown */
320
- .gr-dropdown {
321
- border-radius: 12px !important;
322
- border: 2px solid #e2e8f0 !important;
323
- padding: 12px !important;
324
- font-size: 1em !important;
325
- transition: all 0.3s ease !important;
326
- background: white !important;
327
- }
328
-
329
- .gr-dropdown:focus {
330
- border-color: #667eea !important;
331
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
332
- }
333
-
334
- /* accordion */
335
- .gr-accordion {
336
- background: rgba(255, 255, 255, 0.95) !important;
337
- border-radius: 16px !important;
338
- margin-top: 20px !important;
339
- overflow: hidden !important;
340
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
341
- }
342
-
343
- .gr-accordion-header {
344
- background: linear-gradient(135deg, #f6f9fc 0%, #e9ecef 100%) !important;
345
- padding: 15px 20px !important;
346
- font-weight: 600 !important;
347
- color: #4a5568 !important;
348
- }
349
-
350
- /* sliders */
351
- .gr-slider {
352
- margin: 15px 0 !important;
353
- }
354
-
355
- .gr-slider input[type="range"] {
356
- background: linear-gradient(to right, #667eea 0%, #764ba2 100%) !important;
357
- height: 6px !important;
358
- border-radius: 3px !important;
359
- }
360
-
361
- .gr-slider input[type="range"]::-webkit-slider-thumb {
362
- background: white !important;
363
- border: 3px solid #667eea !important;
364
- width: 20px !important;
365
- height: 20px !important;
366
- border-radius: 50% !important;
367
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2) !important;
368
- }
369
-
370
- /* number input */
371
- .gr-number input {
372
- border-radius: 12px !important;
373
- border: 2px solid #e2e8f0 !important;
374
- padding: 12px !important;
375
- font-size: 1em !important;
376
- transition: all 0.3s ease !important;
377
- }
378
-
379
- .gr-number input:focus {
380
- border-color: #667eea !important;
381
- box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
382
- }
383
-
384
- /* examples */
385
- .gr-examples {
386
- background: rgba(255, 255, 255, 0.95) !important;
387
- border-radius: 16px !important;
388
- padding: 20px !important;
389
- margin-top: 30px !important;
390
- box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1) !important;
391
- }
392
-
393
- .gr-examples-title {
394
- font-size: 1.3em !important;
395
- font-weight: 700 !important;
396
- color: #4a5568 !important;
397
- margin-bottom: 15px !important;
398
- }
399
-
400
- .gr-sample-image {
401
- border-radius: 8px !important;
402
- transition: transform 0.3s ease !important;
403
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1) !important;
404
- }
405
-
406
- .gr-sample-image:hover {
407
- transform: scale(1.05) !important;
408
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2) !important;
409
- }
410
-
411
- /* loading */
412
- .gr-loading {
413
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
414
- animation: pulse 1.5s infinite !important;
415
- }
416
-
417
- @keyframes pulse {
418
- 0% { opacity: 1; }
419
- 50% { opacity: 0.7; }
420
- 100% { opacity: 1; }
421
- }
422
-
423
- /* row spacing */
424
- .gr-row { gap: 20px !important; }
425
-
426
- /* card effect */
427
- .card-style {
428
- background: white;
429
- border-radius: 16px;
430
- padding: 24px;
431
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.07);
432
- transition: all 0.3s ease;
433
- }
434
-
435
- .card-style:hover {
436
- box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
437
- }
438
-
439
- /* icon label */
440
- .icon-label::before { content: "✨ "; font-size: 1.2em; }
441
-
442
- /* responsive */
443
- @media (max-width: 768px) {
444
- #header h1 { font-size: 2.5em; }
445
- .gr-button-primary { padding: 12px 30px !important; font-size: 1em !important; }
446
  }
447
  """
448
 
449
  if __name__ == '__main__':
450
 
451
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
452
- # header
453
  with gr.Column(elem_id="header"):
454
  gr.HTML("""
455
  <h1>✨ CodiFit-AI Virtual Try-On ✨</h1>
456
  <p id="subtitle">Experience the future of fashion with AI-powered virtual clothing try-on</p>
457
  """)
458
-
459
- # main content
460
  with gr.Row(equal_height=True):
461
- # left column - Person Image
462
  with gr.Column(scale=1):
463
- with gr.Group(elem_classes="card-style"):
464
- gr.HTML("<h3 style='text-align: center; color: #667eea; margin-bottom: 15px;'>👤 Person Image</h3>")
465
- person_image = gr.Image(
466
- type="pil",
467
- label="Upload Person Photo",
468
- height=500,
469
- elem_classes="image-container",
470
- show_label=True,
471
- container=True,
472
- interactive=True
473
- )
474
-
475
- # middle column - Object Image and controls
476
  with gr.Column(scale=1):
477
- with gr.Group(elem_classes="card-style"):
478
- gr.HTML("<h3 style='text-align: center; color: #764ba2; margin-bottom: 15px;'>👔 Object to Try</h3>")
479
- object_image = gr.Image(
480
- type="pil",
481
- label="Upload Object Image",
482
- height=400,
483
- elem_classes="image-container",
484
- show_label=True,
485
- container=True,
486
- interactive=True
487
- )
488
- object_class = gr.Dropdown(
489
- label='Select Object Category',
490
- choices=args.object_map.keys(),
491
- elem_classes="icon-label"
492
- )
493
- run_button = gr.Button(
494
- value="🚀 Generate Try-On",
495
- variant='primary',
496
- size="lg"
497
- )
498
-
499
- # right column - Output
500
  with gr.Column(scale=1):
501
- with gr.Group(elem_classes="card-style"):
502
- gr.HTML("<h3 style='text-align: center; color: #667eea; margin-bottom: 15px;'>🎨 Generated Result</h3>")
503
- image_out = gr.Image(
504
- type="pil",
505
- label="Virtual Try-On Result",
506
- height=500,
507
- elem_classes="image-container",
508
- show_label=True,
509
- container=True,
510
- interactive=False
511
- )
512
 
513
- # Advanced Settings
514
- with gr.Accordion("⚙️ Advanced Settings", open=False, elem_classes="card-style"):
515
  with gr.Row():
516
- with gr.Column(scale=1):
517
- guidance_scale = gr.Slider(
518
- label="🎯 Guidance Scale",
519
- info="Higher values produce images closer to the text prompt",
520
- minimum=1,
521
- maximum=50,
522
- value=30,
523
- step=0.1
524
- )
525
- with gr.Column(scale=1):
526
- steps = gr.Slider(
527
- label="🔄 Inference Steps",
528
- info="More steps = better quality but slower",
529
- minimum=1,
530
- maximum=50,
531
- value=20,
532
- step=1
533
- )
534
- with gr.Column(scale=1):
535
- seed = gr.Number(
536
- label="🎲 Random Seed",
537
- info="Use -1 for random generation",
538
- value=-1,
539
- precision=0
540
- )
541
-
542
- # Examples Gallery
543
- gr.HTML("""
544
- <div style='background: rgba(255,255,255,0.95); border-radius: 16px; padding: 25px; margin-top: 30px;'>
545
- <h3 style='text-align: center; color: #4a5568; margin-bottom: 20px; font-size: 1.5em;'>
546
- 📸 Example Gallery
547
- </h3>
548
- <p style='text-align: center; color: #718096; margin-bottom: 20px;'>
549
- Click any example below to try it out instantly!
550
- </p>
551
- </div>
552
- """)
553
-
554
- with gr.Row():
555
- gr.Examples(
556
- examples=[
557
- ['./demo_example/person_top_cloth.jpg', './demo_example/object_top_cloth.jpg', 'top clothes'],
558
- ['./demo_example/person_bottom_cloth.jpg', './demo_example/object_bottom_cloth.jpg', 'bottom clothes'],
559
- ['./demo_example/person_dress.jpg', './demo_example/object_dress.jpg', 'dress'],
560
- ['./demo_example/person_shoes.jpg', './demo_example/object_shoes.jpg', 'shoe'],
561
- ['./demo_example/person_earrings.jpg', './demo_example/object_earrings.jpg', 'earrings'],
562
- ['./demo_example/person_bracelet.jpg', './demo_example/object_bracelet.jpg', 'bracelet'],
563
- ['./demo_example/person_necklace.jpg', './demo_example/object_necklace.jpg', 'necklace'],
564
- ['./demo_example/person_ring.jpg', './demo_example/object_ring.jpg', 'ring'],
565
- ['./demo_example/person_sunglasses.jpg', './demo_example/object_sunglasses.jpg', 'sunglasses'],
566
- ['./demo_example/person_glasses.jpg', './demo_example/object_glasses.jpg', 'glasses'],
567
- ['./demo_example/person_belt.jpg', './demo_example/object_belt.jpg', 'belt'],
568
- ['./demo_example/person_bag.jpg', './demo_example/object_bag.jpg', 'bag'],
569
- ['./demo_example/person_hat.jpg', './demo_example/object_hat.jpg', 'hat'],
570
- ['./demo_example/person_tie.jpg', './demo_example/object_tie.jpg', 'tie'],
571
- ['./demo_example/person_bowtie.jpg', './demo_example/object_bowtie.jpg', 'bow tie'],
572
- ],
573
- inputs=[person_image, object_image, object_class],
574
- examples_per_page=5,
575
- label="Try These Examples"
576
- )
577
-
578
- # Footer
579
- gr.HTML("""
580
- <div style='text-align: center; margin-top: 40px; padding: 20px; background: rgba(255,255,255,0.1); border-radius: 16px;'>
581
- <p style='color: rgba(255,255,255,0.9); font-size: 0.9em;'>
582
- Powered by FLUX.1-Fill and CodiFit-AI | Made with 💜
583
- </p>
584
- </div>
585
- """)
586
 
587
- run_button.click(
588
- generate,
589
- inputs=[person_image, object_image, object_class, steps, guidance_scale, seed],
590
- outputs=[image_out]
591
- )
592
 
593
  demo.launch(server_name="0.0.0.0")
 
61
  def lora_forward(self, active_adapter, x, *args, **kwargs):
62
  result = self.base_layer(x, *args, **kwargs)
63
  if active_adapter is not None:
 
64
  lora_A = self.lora_A[active_adapter]
65
  lora_B = self.lora_B[active_adapter]
66
  dropout = self.lora_dropout[active_adapter]
 
93
 
94
  @spaces.GPU
95
  def generate(person_image, object_image, object_class, steps, guidance_scale, seed):
 
96
  if seed == -1:
97
  seed = random.randint(0, 2**32 - 1)
98
  seed_everything(seed)
99
 
 
100
  max_area = 1024 * 1024
101
+ oW, oH = person_image.width, person_image.height
 
 
102
  ratio = math.sqrt(max_area / (oW * oH))
103
  ratio = min(1, ratio)
104
  tW, tH = int(oW * ratio) // 16 * 16, int(oH * ratio) // 16 * 16
 
108
  ])
109
  person_image = transform(person_image)
110
 
 
111
  ratio = min(tW / object_image.width, tH / object_image.height)
112
  transform = T.Compose([
113
  T.Resize((int(object_image.height * ratio), int(object_image.width * ratio))),
 
120
  min_y = (tH - new_h) // 2
121
  object_image_padded[:, min_y: min_y + new_h, min_x: min_x + new_w] = object_image
122
 
 
123
  prompts = [args.object_map[object_class]] * 2
124
  img_cond = torch.stack([person_image, object_image_padded]).to(dtype=weight_dtype, device=device)
125
  mask = torch.zeros_like(img_cond).to(img_cond)
 
139
  return img
140
 
141
 
142
+ # Custom CSS
143
  custom_css = """
144
+ /* 전체 배경 */
145
  .gradio-container {
146
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
147
  font-family: 'Inter', sans-serif;
148
  }
149
 
150
+ /* === 플레이스홀더 전부 제거 === */
151
+ .gr-image svg,
152
+ .gr-image [data-testid*="placeholder"],
153
+ .gr-image [class*="placeholder"],
154
+ .gr-image [aria-label*="placeholder"],
155
+ .gr-image [class*="svelte"][class*="placeholder"],
156
+ .gr-image .absolute.inset-0.flex.items-center.justify-center,
157
+ .gr-image .flex.items-center.justify-center svg {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  display: none !important;
159
  visibility: hidden !important;
160
  }
161
+ .gr-image [class*="overlay"],
162
+ .gr-image .fixed.inset-0,
163
+ .gr-image .absolute.inset-0 {
164
+ pointer-events: none !important;
 
165
  }
166
 
167
+ /* 이미지 업로드 영역 */
168
+ .gr-image .wrap { background: transparent !important; min-height: 400px !important; }
169
  .gr-image .upload-container {
 
 
 
170
  min-height: 400px !important;
171
+ border: 3px dashed rgba(102, 126, 234, 0.4) !important;
 
 
 
 
 
 
 
 
 
 
 
172
  border-radius: 12px !important;
173
+ background: linear-gradient(135deg, rgba(248, 250, 252, 0.5) 0%, rgba(241, 245, 249, 0.5) 100%) !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  position: relative !important;
175
  }
176
+ /* 이미지 있을 때 */
177
+ .gr-image:has(img) .upload-container { border: none !important; background: transparent !important; }
178
+ /* 안내 텍스트 */
179
  .gr-image .upload-container::after {
180
+ content: "Click or Drag to Upload";
181
+ position: absolute; top: 50%; left: 50%;
182
+ transform: translate(-50%, -50%);
183
+ color: rgba(102, 126, 234, 0.7);
184
+ font-size: 1.05em; font-weight: 500;
185
+ pointer-events: none;
186
+ }
187
+ .gr-image:has(img) .upload-container::after { display: none !important; }
188
+ /* 업로드 이미지 */
189
+ .gr-image img { border-radius: 12px !important; position: relative !important; z-index: 10 !important; }
190
+
191
+ /* 버튼, 라벨 나머지는 그대로 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  .gr-button-primary {
193
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
194
+ color: white !important; border: none !important;
195
+ padding: 15px 40px !important; font-size: 1.2em !important;
196
+ border-radius: 50px !important; cursor: pointer !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  }
198
  """
199
 
200
  if __name__ == '__main__':
201
 
202
  with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
 
203
  with gr.Column(elem_id="header"):
204
  gr.HTML("""
205
  <h1>✨ CodiFit-AI Virtual Try-On ✨</h1>
206
  <p id="subtitle">Experience the future of fashion with AI-powered virtual clothing try-on</p>
207
  """)
 
 
208
  with gr.Row(equal_height=True):
 
209
  with gr.Column(scale=1):
210
+ person_image = gr.Image(type="pil", label="Upload Person Photo", height=500, interactive=True)
 
 
 
 
 
 
 
 
 
 
 
 
211
  with gr.Column(scale=1):
212
+ object_image = gr.Image(type="pil", label="Upload Object Image", height=400, interactive=True)
213
+ object_class = gr.Dropdown(label='Select Object Category', choices=args.object_map.keys())
214
+ run_button = gr.Button(value="🚀 Generate Try-On", variant='primary')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  with gr.Column(scale=1):
216
+ image_out = gr.Image(type="pil", label="Virtual Try-On Result", height=500, interactive=False)
 
 
 
 
 
 
 
 
 
 
217
 
218
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
 
219
  with gr.Row():
220
+ guidance_scale = gr.Slider(label="🎯 Guidance Scale", minimum=1, maximum=50, value=30, step=0.1)
221
+ steps = gr.Slider(label="🔄 Inference Steps", minimum=1, maximum=50, value=20, step=1)
222
+ seed = gr.Number(label="🎲 Random Seed", value=-1, precision=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
+ run_button.click(generate,
225
+ inputs=[person_image, object_image, object_class, steps, guidance_scale, seed],
226
+ outputs=[image_out])
 
 
227
 
228
  demo.launch(server_name="0.0.0.0")