samikshachavan commited on
Commit
7f7d839
Β·
verified Β·
1 Parent(s): f7a3366

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -100
app.py CHANGED
@@ -3,58 +3,14 @@ from gradio_client import Client, handle_file
3
  from PIL import Image
4
  import tempfile, os, time, random
5
 
6
- # ══════════════════════════════════════════════════════════════════
7
- # CPU-ONLY VERSION β€” No GPU needed, No ZeroGPU subscription
8
- # Strategy: Call HF Space APIs (3 backup spaces)
9
- # If all busy β†’ friendly retry message
10
- # ══════════════════════════════════════════════════════════════════
11
-
12
- # Multiple backup spaces β€” tries each one
13
  SPACES = [
14
  "yisol/IDM-VTON",
15
- "yisol/IDM-VTON-DC",
16
  "Nymbo/Virtual-Try-On",
17
  ]
18
 
19
- def save_tmp(img: Image.Image) -> str:
20
- p = tempfile.mktemp(suffix=".jpg")
21
- img.save(p, quality=95)
22
- return p
23
-
24
- def cleanup(*paths):
25
- for p in paths:
26
- try:
27
- if p and os.path.exists(p): os.remove(p)
28
- except: pass
29
-
30
- def auto_crop(cloth: Image.Image) -> bool:
31
- return (cloth.height / max(cloth.width, 1)) > 1.3
32
-
33
- def try_space(space, person, cloth, steps, seed):
34
- """Try one HF Space β€” returns result image or raises."""
35
- p, c = save_tmp(person), save_tmp(cloth)
36
- try:
37
- client = Client(space, verbose=False)
38
- result = client.predict(
39
- dict={"background": handle_file(p), "layers": [], "composite": None},
40
- garm_img = handle_file(c),
41
- garment_des = "clothing item",
42
- is_checked = True,
43
- is_checked_crop = auto_crop(cloth),
44
- denoise_steps = steps,
45
- seed = seed,
46
- api_name = "/tryon"
47
- )
48
- cleanup(p, c)
49
- return Image.open(result[0]).convert("RGB")
50
- except Exception as e:
51
- cleanup(p, c)
52
- raise e
53
-
54
-
55
  def virtual_tryon(person_img, cloth_img, quality):
56
  if person_img is None:
57
- return None, "⚠️ Please upload your photo first!"
58
  if cloth_img is None:
59
  return None, "⚠️ Please upload a clothing image!"
60
 
@@ -62,99 +18,128 @@ def virtual_tryon(person_img, cloth_img, quality):
62
  seed = random.randint(0, 9999)
63
  t0 = time.time()
64
 
65
- last_error = ""
 
 
 
 
 
 
 
 
66
  for space in SPACES:
67
  try:
68
  print(f"Trying {space}...")
69
- result = try_space(space, person_img, cloth_img, steps, seed)
70
- elapsed = time.time() - t0
71
- short = space.split("/")[-1]
72
- return result, f"βœ… Done in {elapsed:.1f}s via {short}!"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  except Exception as e:
74
- last_error = str(e)
75
- if "TooManyRequests" in last_error or "429" in last_error:
76
- print(f"⏳ {space} busy, trying next...")
77
- time.sleep(5)
78
- continue
79
- print(f"❌ {space} error: {last_error[:80]}")
80
  continue
81
 
82
- # All spaces failed
83
- if "TooManyRequests" in last_error or "429" in last_error:
84
- return None, (
85
- "⏳ All servers are busy right now.\n"
86
- "Please wait 2-3 minutes and try again!\n"
87
- "πŸ’‘ Tip: Try during off-peak hours (early morning or late night)"
88
- )
89
- return None, f"❌ Could not connect. Please try again. ({last_error[:100]})"
90
 
91
 
92
- # ── UI ────────────────────────────────────────────────────────────
93
  with gr.Blocks(
94
- title="πŸ‘— AI Virtual Try-On",
95
  theme=gr.themes.Soft(primary_hue="violet", secondary_hue="pink"),
96
- css="""
97
- .tip { background:linear-gradient(135deg,#f0e8ff,#ffe8f4);
98
- border-radius:14px; padding:12px 16px;
99
- font-size:.85em; color:#555; margin-top:8px;
100
- border:1px solid #e0d0ff }
101
- footer { display:none !important }
102
- """
103
  ) as demo:
104
 
105
  gr.HTML("""
106
- <div style="text-align:center;padding:24px 0 12px">
107
- <h1 style="font-size:2.4em;font-weight:900;
108
- background:linear-gradient(90deg,#7c3aed,#db2777);
109
- -webkit-background-clip:text;-webkit-text-fill-color:transparent">
110
  πŸ‘— AI Virtual Try-On
111
  </h1>
112
- <p style="color:#888;font-size:1em;margin-top:4px">
113
- Upload your photo + clothing β€” see how it looks on you!<br>
114
- <b style="color:#7c3aed">Powered by IDM-VTON Β· Auto-detects garment type</b>
115
- </p>
116
  </div>
117
  """)
118
 
119
- with gr.Row(equal_height=True):
120
  with gr.Column():
121
  gr.Markdown("### πŸ“· Step 1 β€” Your Photo")
122
- p_in = gr.Image(label="Upload full-body photo", type="pil", height=380)
123
- gr.HTML('<div class="tip">πŸ’‘ Stand straight Β· Full body visible Β· Good lighting Β· Plain background</div>')
124
 
125
  with gr.Column():
126
  gr.Markdown("### πŸ‘— Step 2 β€” Clothing Item")
127
- c_in = gr.Image(label="Upload clothing product photo", type="pil", height=380)
128
- gr.HTML('<div class="tip">πŸ’‘ White background product photo Β· AI auto-detects dress vs top</div>')
129
 
130
  with gr.Column():
131
- gr.Markdown("### ✨ Step 3 β€” Result")
132
  r_out = gr.Image(label="Try-On Result", type="pil", height=380)
133
- status = gr.Textbox(label="Status", interactive=False,
134
- placeholder="Result will appear here…")
135
 
136
  with gr.Row():
137
  quality = gr.Radio(
138
  ["Fast ⚑", "Balanced βš–οΈ", "Best Quality πŸ’Ž"],
139
  value="Balanced βš–οΈ",
140
  label="Quality",
141
- info="Fast=20 steps Β· Balanced=30 Β· Best=40",
142
- scale=2,
143
  )
144
- gr.Button("πŸš€ Generate Try-On!", variant="primary", size="lg", scale=1).click(
 
 
145
  fn=virtual_tryon,
146
  inputs=[p_in, c_in, quality],
147
- outputs=[r_out, status],
148
  )
149
 
150
  gr.HTML("""
151
- <div style="text-align:center;margin-top:18px;padding:14px;
152
- background:linear-gradient(135deg,#f5f0ff,#fff0f8);
153
- border-radius:14px;color:#666;font-size:.85em;
154
- border:1px solid #e8d8ff">
155
- πŸ€– Uses <b>IDM-VTON API</b> with 3 backup servers Β·
156
- Auto-retries if busy Β· No GPU subscription needed Β· 100% Free
157
  </div>
158
  """)
159
 
160
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  from PIL import Image
4
  import tempfile, os, time, random
5
 
 
 
 
 
 
 
 
6
  SPACES = [
7
  "yisol/IDM-VTON",
 
8
  "Nymbo/Virtual-Try-On",
9
  ]
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  def virtual_tryon(person_img, cloth_img, quality):
12
  if person_img is None:
13
+ return None, "⚠️ Please upload your photo!"
14
  if cloth_img is None:
15
  return None, "⚠️ Please upload a clothing image!"
16
 
 
18
  seed = random.randint(0, 9999)
19
  t0 = time.time()
20
 
21
+ # Save uploaded images to temp files
22
+ p_path = tempfile.mktemp(suffix=".jpg")
23
+ c_path = tempfile.mktemp(suffix=".jpg")
24
+ person_img.save(p_path)
25
+ cloth_img.save(c_path)
26
+
27
+ # Auto detect dress vs top
28
+ is_dress = (cloth_img.height / max(cloth_img.width, 1)) > 1.3
29
+
30
  for space in SPACES:
31
  try:
32
  print(f"Trying {space}...")
33
+ client = Client(space, verbose=False)
34
+ result = client.predict(
35
+ dict={
36
+ "background": handle_file(p_path),
37
+ "layers": [],
38
+ "composite": None
39
+ },
40
+ garm_img = handle_file(c_path),
41
+ garment_des = "dress" if is_dress else "shirt",
42
+ is_checked = True,
43
+ is_checked_crop = is_dress,
44
+ denoise_steps = steps,
45
+ seed = seed,
46
+ api_name = "/tryon"
47
+ )
48
+ # Cleanup temp files
49
+ try: os.remove(p_path)
50
+ except: pass
51
+ try: os.remove(c_path)
52
+ except: pass
53
+
54
+ result_img = Image.open(result[0]).convert("RGB")
55
+ elapsed = time.time() - t0
56
+ return result_img, f"βœ… Done in {elapsed:.1f}s!"
57
+
58
  except Exception as e:
59
+ print(f"❌ {space} failed: {str(e)[:80]}")
60
+ time.sleep(3)
 
 
 
 
61
  continue
62
 
63
+ # Cleanup
64
+ try: os.remove(p_path)
65
+ except: pass
66
+ try: os.remove(c_path)
67
+ except: pass
68
+
69
+ return None, "⏳ Servers busy β€” please wait 2 minutes and try again!"
 
70
 
71
 
 
72
  with gr.Blocks(
73
+ title="AI Virtual Try-On",
74
  theme=gr.themes.Soft(primary_hue="violet", secondary_hue="pink"),
 
 
 
 
 
 
 
75
  ) as demo:
76
 
77
  gr.HTML("""
78
+ <div style='text-align:center;padding:20px 0'>
79
+ <h1 style='font-size:2.2em;font-weight:900;
80
+ background:linear-gradient(90deg,#7c3aed,#db2777);
81
+ -webkit-background-clip:text;-webkit-text-fill-color:transparent'>
82
  πŸ‘— AI Virtual Try-On
83
  </h1>
84
+ <p style='color:#888'>Upload your photo + clothing β€” AI shows how it looks on you!</p>
 
 
 
85
  </div>
86
  """)
87
 
88
+ with gr.Row():
89
  with gr.Column():
90
  gr.Markdown("### πŸ“· Step 1 β€” Your Photo")
91
+ p_in = gr.Image(label="Full-body photo", type="pil", height=380)
92
+ gr.HTML("<div style='background:#f5f0ff;border-radius:12px;padding:10px 14px;font-size:.85em;color:#555;margin-top:8px'>πŸ’‘ Stand straight Β· Good lighting Β· Plain background</div>")
93
 
94
  with gr.Column():
95
  gr.Markdown("### πŸ‘— Step 2 β€” Clothing Item")
96
+ c_in = gr.Image(label="Clothing product photo", type="pil", height=380)
97
+ gr.HTML("<div style='background:#f5f0ff;border-radius:12px;padding:10px 14px;font-size:.85em;color:#555;margin-top:8px'>πŸ’‘ White background Β· AI detects garment type automatically</div>")
98
 
99
  with gr.Column():
100
+ gr.Markdown("### ✨ Step 3 β€” Your Result")
101
  r_out = gr.Image(label="Try-On Result", type="pil", height=380)
102
+ status = gr.Textbox(label="Status", interactive=False)
 
103
 
104
  with gr.Row():
105
  quality = gr.Radio(
106
  ["Fast ⚑", "Balanced βš–οΈ", "Best Quality πŸ’Ž"],
107
  value="Balanced βš–οΈ",
108
  label="Quality",
109
+ scale=2
 
110
  )
111
+ gr.Button(
112
+ "πŸš€ Generate Try-On!", variant="primary", size="lg", scale=1
113
+ ).click(
114
  fn=virtual_tryon,
115
  inputs=[p_in, c_in, quality],
116
+ outputs=[r_out, status]
117
  )
118
 
119
  gr.HTML("""
120
+ <div style='text-align:center;margin-top:16px;padding:12px;
121
+ background:#f8f4ff;border-radius:12px;color:#666;font-size:.83em'>
122
+ πŸ€– Powered by IDM-VTON Β· Auto-detects garment type Β· 100% Free
 
 
 
123
  </div>
124
  """)
125
 
126
+ demo.launch()
127
+ ```
128
+
129
+ ---
130
+
131
+ ## Fix `README.md` β€” paste this:
132
+ ```
133
+ ---
134
+ title: AI Virtual Try-On
135
+ emoji: πŸ‘—
136
+ colorFrom: purple
137
+ colorTo: pink
138
+ sdk: gradio
139
+ sdk_version: 5.23.0
140
+ app_file: app.py
141
+ pinned: true
142
+ license: mit
143
+ ---
144
+
145
+ # πŸ‘— AI Virtual Try-On