aeon12 commited on
Commit
3ee761b
·
verified ·
1 Parent(s): 873050b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +167 -0
app.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import base64
4
+ import time
5
+ import os
6
+ from PIL import Image
7
+ import io
8
+
9
+ API_KEY = os.environ.get('RUNPOD_API_KEY')
10
+ API_URL = 'https://api.runpod.ai/v2/31jyh9kh7nwyga'
11
+
12
+ cloth_images = [
13
+ {"url": "https://i.postimg.cc/7ZzLZtbc/hmgoepprod-4-1.jpg", "label": "Jacket 1"},
14
+ {"url": "https://i.postimg.cc/7Yd6DrP0/hmgoepprod-6.jpg", "label": "Jacket 2"},
15
+ {"url": "https://i.postimg.cc/8z40MNFr/hnm.png", "label": "Jacket 3"},
16
+ {"url": "https://i.postimg.cc/mkqbb74B/hmgoepprod-5.jpg", "label": "Jacket 4"},
17
+ {"url": "https://i.postimg.cc/vBwySGzH/hmgoepprod.jpg", "label": "Jacket 5"},
18
+ {"url": "https://i.postimg.cc/6qSYYprM/Whats-App-Image-2024-08-18-at-13-45-37-2.jpg", "label": "Jacket 6"},
19
+ {"url": "https://i.postimg.cc/tJHhTnzQ/Screenshot-2024-08-20-at-10-04-29-PM.png", "label": "Jacket 7"},
20
+ {"url": "https://i.postimg.cc/yxQYGwxQ/Screenshot-2024-08-20-at-10-06-28-PM.png", "label": "Jacket 8"},
21
+ ]
22
+
23
+ user_images = [
24
+ {"url": "https://iili.io/dEk7qtp.md.jpg", "label": "User 1 (Male)"},
25
+ {"url": "https://iili.io/d1RpKBa.md.jpg", "label": "User 2 (Female)"},
26
+ {"url": "https://i.postimg.cc/QtzQrnFt/Whats-App-Image-2024-08-18-at-13-42-10.jpg", "label": "User 3 (Female)"},
27
+ {"url": "https://i.postimg.cc/rsKLDzyj/Whats-App-Image-2024-08-19-at-12-13-41.jpg", "label": "User 4 (Female)"},
28
+ {"url": "https://i.postimg.cc/cHkpGZ7n/Whats-App-Image-2024-08-19-at-00-27-16-1.jpg", "label": "User 5 (Female)"},
29
+ {"url": "https://i.postimg.cc/g2bfWghN/Whats-App-Image-2024-08-19-at-12-13-41-1.jpg", "label": "User 6 (Female)"},
30
+ ]
31
+
32
+ scene_options = [
33
+ "Gym", "City Street", "Party", "Beach", "Office", "Park", "Cafe",
34
+ "Shopping Mall", "Concert", "Sports Stadium"
35
+ ]
36
+
37
+ def get_base64_from_url(url):
38
+ response = requests.get(url)
39
+ return base64.b64encode(response.content).decode('utf-8')
40
+
41
+ def get_base64_from_image(image):
42
+ buffered = io.BytesIO()
43
+ image.save(buffered, format="PNG")
44
+ return base64.b64encode(buffered.getvalue()).decode('utf-8')
45
+
46
+ def generate_tryon(cloth_input, user_input, scene):
47
+ if isinstance(cloth_input, str): # URL selected
48
+ cloth_base64 = get_base64_from_url(cloth_input)
49
+ else: # Image uploaded
50
+ cloth_base64 = get_base64_from_image(cloth_input)
51
+
52
+ if isinstance(user_input, str): # URL selected
53
+ user_base64 = get_base64_from_url(user_input)
54
+ else: # Image uploaded
55
+ user_base64 = get_base64_from_image(user_input)
56
+
57
+ input_data = {
58
+ "user_image": user_base64,
59
+ "product_image": cloth_base64,
60
+ "background": scene
61
+ }
62
+
63
+ response = requests.post(
64
+ f"{API_URL}/run",
65
+ headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
66
+ json={"input": input_data}
67
+ )
68
+
69
+ if response.status_code != 200:
70
+ raise Exception(f"API request failed with status {response.status_code}: {response.text}")
71
+
72
+ job_id = response.json()['id']
73
+
74
+ while True:
75
+ status_response = requests.get(
76
+ f"{API_URL}/status/{job_id}",
77
+ headers={"Authorization": f"Bearer {API_KEY}"}
78
+ )
79
+
80
+ if status_response.status_code != 200:
81
+ raise Exception(f"Status check failed with status {status_response.status_code}: {status_response.text}")
82
+
83
+ status_data = status_response.json()
84
+ if status_data['status'] == 'COMPLETED':
85
+ output_base64 = status_data['output']['output']
86
+ output_image = Image.open(io.BytesIO(base64.b64decode(output_base64)))
87
+ return output_image
88
+ elif status_data['status'] == 'FAILED':
89
+ raise Exception(f"Job processing failed: {status_data}")
90
+
91
+ time.sleep(2)
92
+
93
+ def tryon_interface(cloth_selection, cloth_upload, user_selection, user_upload, scene_selection, custom_scene):
94
+ cloth_input = cloth_upload if cloth_upload is not None else cloth_selection
95
+ user_input = user_upload if user_upload is not None else user_selection
96
+ scene = custom_scene if custom_scene else scene_selection
97
+
98
+ if not cloth_input or not user_input or not scene:
99
+ return None, "Please select or upload both clothing and user images, and specify a scene."
100
+
101
+ try:
102
+ result_image = generate_tryon(cloth_input, user_input, scene)
103
+ return result_image, "Try-on image generated successfully!"
104
+ except Exception as e:
105
+ return None, f"Error: {str(e)}"
106
+
107
+ def create_image_grid(images, labels, columns=4):
108
+ rows = -(-len(images) // columns) # Ceiling division
109
+ cell_width = 200
110
+ cell_height = 250
111
+ grid = Image.new('RGB', (columns * cell_width, rows * cell_height), color='white')
112
+
113
+ for i, (url, label) in enumerate(zip(images, labels)):
114
+ response = requests.get(url)
115
+ img = Image.open(io.BytesIO(response.content))
116
+ img.thumbnail((cell_width, cell_height - 30))
117
+
118
+ x = (i % columns) * cell_width
119
+ y = (i // columns) * cell_height
120
+
121
+ grid.paste(img, (x + (cell_width - img.width) // 2, y))
122
+
123
+ # Add label
124
+ from PIL import ImageDraw, ImageFont
125
+ draw = ImageDraw.Draw(grid)
126
+ font = ImageFont.load_default()
127
+ label_width = draw.textlength(label, font=font)
128
+ draw.text((x + (cell_width - label_width) // 2, y + cell_height - 20), label, fill="black", font=font)
129
+
130
+ return grid
131
+
132
+ with gr.Blocks() as demo:
133
+ gr.Markdown("# Virtual Try-On Application")
134
+
135
+ with gr.Row():
136
+ with gr.Column():
137
+ gr.Markdown("## Available Clothing")
138
+ cloth_grid = gr.Image(create_image_grid([img["url"] for img in cloth_images],
139
+ [img["label"] for img in cloth_images]))
140
+ cloth_selection = gr.Dropdown(choices=[img["url"] for img in cloth_images],
141
+ label="Select Clothing")
142
+ cloth_upload = gr.Image(label="Or Upload Custom Clothing")
143
+
144
+ with gr.Column():
145
+ gr.Markdown("## Available User Images")
146
+ user_grid = gr.Image(create_image_grid([img["url"] for img in user_images],
147
+ [img["label"] for img in user_images]))
148
+ user_selection = gr.Dropdown(choices=[img["url"] for img in user_images],
149
+ label="Select User Image")
150
+ user_upload = gr.Image(label="Or Upload Custom User Image")
151
+
152
+ with gr.Row():
153
+ scene_selection = gr.Dropdown(choices=scene_options, label="Select Scene")
154
+ custom_scene = gr.Textbox(label="Or Enter Custom Scene")
155
+
156
+ generate_button = gr.Button("Generate Try-On")
157
+
158
+ output_image = gr.Image(label="Try-On Result")
159
+ output_text = gr.Textbox(label="Status")
160
+
161
+ generate_button.click(
162
+ tryon_interface,
163
+ inputs=[cloth_selection, cloth_upload, user_selection, user_upload, scene_selection, custom_scene],
164
+ outputs=[output_image, output_text]
165
+ )
166
+
167
+ demo.launch()