aiprovider25 commited on
Commit
02856e5
·
verified ·
1 Parent(s): 35d53eb

init project

Browse files
.gitattributes CHANGED
@@ -33,3 +33,11 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ images[[:space:]]/garment/try-on-garment-2.png filter=lfs diff=lfs merge=lfs -text
37
+ images[[:space:]]/garment/try-on-garment-4.jpg filter=lfs diff=lfs merge=lfs -text
38
+ images[[:space:]]/garment/try-on-garment.png filter=lfs diff=lfs merge=lfs -text
39
+ images[[:space:]]/models/try-on-model-2.png filter=lfs diff=lfs merge=lfs -text
40
+ images[[:space:]]/models/try-on-model-3.png filter=lfs diff=lfs merge=lfs -text
41
+ images[[:space:]]/models/try-on-model-4.png filter=lfs diff=lfs merge=lfs -text
42
+ images[[:space:]]/models/try-on-model.png filter=lfs diff=lfs merge=lfs -text
43
+ images[[:space:]]/results/after-try-on.jpg filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import base64
3
+ from PIL import Image
4
+ from io import BytesIO
5
+ import os
6
+ from tryon_api_client import TryOnAPIClient
7
+
8
+ # Configuration
9
+ API_URL = os.environ.get("API_BASE_URL", "http://localhost:5001")
10
+ client = TryOnAPIClient(base_url=API_URL)
11
+
12
+ def process_tryon(person_img, garment_img, garment_type):
13
+ # Validate inputs
14
+ if not person_img or not garment_img:
15
+ raise gr.Error("⚠️ Please upload both Person and Garment images.")
16
+
17
+ # Validate file formats
18
+ try:
19
+ valid_extensions = ('.png', '.jpg', '.jpeg')
20
+ if not person_img.lower().endswith(valid_extensions):
21
+ raise gr.Error("⚠️ Person image must be PNG, JPEG, or JPG format.")
22
+ if not garment_img.lower().endswith(valid_extensions):
23
+ raise gr.Error("⚠️ Garment image must be PNG, JPEG, or JPG format.")
24
+ except AttributeError:
25
+ raise gr.Error("⚠️ Invalid image file. Please upload valid image files.")
26
+
27
+ try:
28
+ # 1. Create Task
29
+ try:
30
+ task_data = client.create_task(person_img, garment_img, garment_type)
31
+ except ConnectionError:
32
+ raise gr.Error("🔌 Cannot connect to the Try-On service. Please check if the API server is running.")
33
+ except TimeoutError:
34
+ raise gr.Error("⏱️ Connection timeout. The server is taking too long to respond.")
35
+ except Exception as e:
36
+ raise gr.Error(f"❌ Failed to create try-on task: {str(e)}")
37
+
38
+ task_id = task_data.get('task_id')
39
+ if not task_id:
40
+ raise gr.Error("❌ No task ID returned from API. Please try again.")
41
+
42
+ # 2. Wait for Completion using Client logic
43
+ try:
44
+ result = client.wait_for_completion(task_id)
45
+ except TimeoutError:
46
+ raise gr.Error("⏱️ Try-on process is taking too long. Please try again with smaller images.")
47
+ except Exception as e:
48
+ raise gr.Error(f"❌ Failed while processing try-on: {str(e)}")
49
+
50
+ # 3. Process result
51
+ image_base64 = result.get('image_base64')
52
+ if image_base64:
53
+ try:
54
+ return base64_to_image(image_base64)
55
+ except Exception as e:
56
+ raise gr.Error(f"❌ Failed to decode result image: {str(e)}")
57
+ else:
58
+ raise gr.Error("❌ Try-on completed but no image was generated. Please try again.")
59
+
60
+ except gr.Error:
61
+ # Re-raise Gradio errors as-is
62
+ raise
63
+ except Exception as e:
64
+ # Catch any unexpected errors
65
+ raise gr.Error(f"❌ Unexpected error occurred: {str(e)}")
66
+
67
+ def base64_to_image(base64_string):
68
+ try:
69
+ image_data = base64.b64decode(base64_string)
70
+ image = Image.open(BytesIO(image_data))
71
+ return image
72
+ except base64.binascii.Error:
73
+ raise ValueError("Invalid base64 string format")
74
+ except Exception as e:
75
+ raise ValueError(f"Cannot decode image: {str(e)}")
76
+
77
+ # UI Layout
78
+ with gr.Blocks(title="Virtual Try-On") as app:
79
+ gr.Markdown("# 👕 Virtual Try-On Demo")
80
+ gr.Markdown("Upload a person image and a garment image to see the magic")
81
+ gr.HTML(
82
+ """
83
+ <center>
84
+ <a href="https://rapidapi.com/aiproviderlabs/api/virtual-outfit-try-on-api"
85
+ target="_blank"
86
+ rel="noopener noreferrer"
87
+ style="display:inline-flex;align-items:center;gap:8px;padding:8px 16px;border-radius:8px;border:1px solid #ccc;text-decoration:none;font-family:sans-serif;">
88
+ <img src="https://files.readme.io/9336831-small-rapid-logo-favicon.png"
89
+ style="width:16px;height:16px;">
90
+ Check out the API @ RapidAPI.com
91
+ </a>
92
+ </center>
93
+ """
94
+ )
95
+
96
+ with gr.Row():
97
+ gr.Markdown("### Before - After Example")
98
+
99
+ with gr.Row():
100
+ gr.Image(value="images /models/try-on-model.png", label="Model", interactive=False, height=300)
101
+ gr.Image(value="images /garment/try-on-garment.png", label="Garment - Full Set", interactive=False, height=300)
102
+ gr.Image(value="images /results/after-try-on.jpg", label="Result", interactive=False, height=300)
103
+
104
+ with gr.Row():
105
+ gr.Markdown("### Try-On Example")
106
+
107
+ with gr.Row():
108
+ with gr.Column():
109
+ person_input = gr.Image(
110
+ type="filepath",
111
+ label="Person Image (PNG, JPEG, JPG only)",
112
+ height=400
113
+ )
114
+ gr.Examples(
115
+ examples=[
116
+ "images /models/try-on-model.png",
117
+ "images /models/try-on-model-2.png",
118
+ "images /models/try-on-model-3.png",
119
+ "images /models/try-on-model-4.png",
120
+ ],
121
+ inputs=person_input
122
+ )
123
+ garment_input = gr.Image(
124
+ type="filepath",
125
+ label="Garment Image (PNG, JPEG, JPG only)",
126
+ height=400
127
+ )
128
+ gr.Examples(
129
+ examples=[
130
+ "images /garment/try-on-garment.png",
131
+ "images /garment/try-on-garment-2.png",
132
+ "images /garment/try-on-garment-3.jpg",
133
+ "images /garment/try-on-garment-4.jpg",
134
+ ],
135
+ inputs=garment_input
136
+ )
137
+
138
+ garment_type_input = gr.Radio(
139
+ choices=["top", "bottom", "fullset"],
140
+ value="top",
141
+ label="Garment Type",
142
+ info="Select the type of clothing you are trying on."
143
+ )
144
+
145
+ run_btn = gr.Button("🚀 Start Try-On", variant="primary")
146
+
147
+ with gr.Column():
148
+ result_output = gr.Image(label="Try-On Result", height=400)
149
+
150
+ run_btn.click(
151
+ fn=process_tryon,
152
+ inputs=[person_input, garment_input, garment_type_input],
153
+ outputs=result_output
154
+ )
155
+
156
+ if __name__ == "__main__":
157
+ app.launch(server_name="0.0.0.0", server_port=7860)
images /garment/try-on-garment-2.png ADDED

Git LFS Details

  • SHA256: b712b0bff28374a0fba9dbe5636920e92bc818fb55f37c013f025479cbec2dd3
  • Pointer size: 131 Bytes
  • Size of remote file: 270 kB
images /garment/try-on-garment-3.jpg ADDED
images /garment/try-on-garment-4.jpg ADDED

Git LFS Details

  • SHA256: b4f4f642b215dc461a91df41d254ea00cdac9a2d964916da95f4db259ee26c45
  • Pointer size: 131 Bytes
  • Size of remote file: 182 kB
images /garment/try-on-garment.png ADDED

Git LFS Details

  • SHA256: 834cec2d9215778fe90846ed3f62201810f54a7c46adf211e1f1c8030914cff2
  • Pointer size: 131 Bytes
  • Size of remote file: 245 kB
images /models/try-on-model-2.png ADDED

Git LFS Details

  • SHA256: 3fe85dcb9d169a2b4f1535ca0de732c0632312d24ca0a7e5b99b2cf971dd48cd
  • Pointer size: 131 Bytes
  • Size of remote file: 242 kB
images /models/try-on-model-3.png ADDED

Git LFS Details

  • SHA256: d5dd7bd184f48380dcb6a81e3662d681e13779714704c79df34be849aaa04833
  • Pointer size: 131 Bytes
  • Size of remote file: 226 kB
images /models/try-on-model-4.png ADDED

Git LFS Details

  • SHA256: e802531cf538aaed7113370022e8d7c5fb9d3e23585dd275897936a525515298
  • Pointer size: 131 Bytes
  • Size of remote file: 231 kB
images /models/try-on-model.png ADDED

Git LFS Details

  • SHA256: dbe7c81405310266a4095fc3dbfb8b9a54e037451b20f66e288b806720a7f134
  • Pointer size: 131 Bytes
  • Size of remote file: 185 kB
images /results/after-try-on.jpg ADDED

Git LFS Details

  • SHA256: 0920943835f8d37a2e9bcb9d3f384666ece3f3a26c51a1abef0504870627eda9
  • Pointer size: 131 Bytes
  • Size of remote file: 264 kB
tryon_api_client.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import time
3
+ import os
4
+
5
+ class TryOnAPIClient:
6
+ def __init__(self, base_url=None):
7
+ self.base_url = base_url or os.environ.get("API_BASE_URL", "http://localhost:5001")
8
+ self.headers = {}
9
+
10
+ rapid_key = os.environ.get("X_RAPIDAPI_KEY")
11
+ rapid_host = os.environ.get("X_RAPIDAPI_HOST")
12
+
13
+ if rapid_key:
14
+ self.headers["x-rapidapi-key"] = rapid_key
15
+ if rapid_host:
16
+ self.headers["x-rapidapi-host"] = rapid_host
17
+
18
+ def create_task(self, person_image_path, garment_image_path, garment_type):
19
+ """
20
+ Uploads images to create a try-on task.
21
+ """
22
+ url = f"{self.base_url}/try-on/file"
23
+
24
+ files = {
25
+ 'person_image': open(person_image_path, 'rb'),
26
+ 'garment_image': open(garment_image_path, 'rb')
27
+ }
28
+
29
+ data = {
30
+ 'garment_type': garment_type
31
+ }
32
+
33
+ try:
34
+ response = requests.post(url, files=files, data=data, headers=self.headers, timeout=60)
35
+
36
+ if response.status_code != 200:
37
+ error_msg = response.json().get('error', 'Unknown Error')
38
+ raise Exception(f"Task Creation Failed: {error_msg}")
39
+
40
+ return response.json()
41
+
42
+ finally:
43
+ # Ensure files are closed
44
+ files['person_image'].close()
45
+ files['garment_image'].close()
46
+
47
+ def check_progress(self, task_id):
48
+ """
49
+ Checks the progress of a task.
50
+ """
51
+ url = f"{self.base_url}/try-on/tasks/{task_id}/progress"
52
+ response = requests.get(url, headers=self.headers, timeout=30)
53
+
54
+ if response.status_code != 200:
55
+ raise Exception(f"Error checking progress: {response.text}")
56
+
57
+ return response.json()
58
+
59
+ def wait_for_completion(self, task_id, timeout=600, poll_interval=2):
60
+ """
61
+ Polls for task completion.
62
+ Returns the result dictionary (with image_base64) or raises Exception.
63
+ """
64
+ start_time = time.time()
65
+
66
+ while (time.time() - start_time) < timeout:
67
+ try:
68
+ data = self.check_progress(task_id)
69
+ except Exception as e:
70
+ print(f"Warning during poll: {e}")
71
+ time.sleep(poll_interval)
72
+ continue
73
+
74
+ status = data.get('status')
75
+
76
+ if status == 'FINISHED':
77
+ return data
78
+ elif status == 'FAILED':
79
+ raise Exception("Task failed on server.")
80
+
81
+ time.sleep(poll_interval)
82
+
83
+ raise Exception("Operation timed out.")