Anurag181011 commited on
Commit
1963c70
·
1 Parent(s): ba675e2

Intial commit

Browse files
Files changed (1) hide show
  1. app.py +291 -0
app.py CHANGED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import gradio as gr
3
+ import numpy as np
4
+ import cv2
5
+ import os
6
+ import base64
7
+
8
+ from try_on_diffusion_client import TryOnDiffusionClient
9
+
10
+ LOG_LEVEL = logging.INFO
11
+ LOG_FORMAT = "%(asctime)s %(thread)-8s %(name)-16s %(levelname)-8s %(message)s"
12
+ LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
13
+
14
+ EXAMPLE_PATH = os.path.join(os.path.dirname(__file__), "examples")
15
+
16
+ API_URL = os.getenv("TRY_ON_DIFFUSION_DEMO_API_URL", "http://localhost:8000")
17
+ API_KEY = os.getenv("TRY_ON_DIFFUSION_DEMO_API_KEY", "")
18
+
19
+ SHOW_RAPIDAPI_LINK = os.getenv("TRY_ON_DIFFUSION_DEMO_SHOW_RAPIDAPI_LINK", "1") == "1"
20
+
21
+ CONCURRENCY_LIMIT = int(os.getenv("TRY_ON_DIFFUSION_DEMO_CONCURRENCY_LIMIT", "2"))
22
+
23
+ logging.basicConfig(level=LOG_LEVEL, format=LOG_FORMAT, datefmt=LOG_DATE_FORMAT)
24
+
25
+ client = TryOnDiffusionClient(base_url=API_URL, api_key=API_KEY)
26
+
27
+
28
+ def get_image_base64(file_name: str) -> str:
29
+ _, ext = os.path.splitext(file_name.lower())
30
+
31
+ content_type = "image/jpeg"
32
+
33
+ if ext == ".png":
34
+ content_type = "image/png"
35
+ elif ext == ".webp":
36
+ content_type = "image/webp"
37
+ elif ext == ".gif":
38
+ content_type = "image/gif"
39
+
40
+ with open(file_name, "rb") as f:
41
+ return f"data:{content_type};base64," + base64.b64encode(f.read()).decode("utf-8")
42
+
43
+
44
+ def get_examples(example_dir: str) -> list[str]:
45
+ file_list = [f for f in os.listdir(os.path.join(EXAMPLE_PATH, example_dir)) if f.endswith(".jpg")]
46
+ file_list.sort()
47
+
48
+ return [os.path.join(EXAMPLE_PATH, example_dir, f) for f in file_list]
49
+
50
+
51
+ def try_on(
52
+ clothing_image: np.ndarray = None,
53
+ clothing_prompt: str = None,
54
+ avatar_image: np.ndarray = None,
55
+ avatar_prompt: str = None,
56
+ avatar_sex: str = None,
57
+ background_image: np.ndarray = None,
58
+ background_prompt: str = None,
59
+ seed: int = -1,
60
+ ) -> tuple:
61
+ result = client.try_on_file(
62
+ clothing_image=cv2.cvtColor(clothing_image, cv2.COLOR_RGB2BGR) if clothing_image is not None else None,
63
+ clothing_prompt=clothing_prompt,
64
+ avatar_image=cv2.cvtColor(avatar_image, cv2.COLOR_RGB2BGR) if avatar_image is not None else None,
65
+ avatar_prompt=avatar_prompt,
66
+ avatar_sex=avatar_sex if avatar_sex in ["male", "female"] else None,
67
+ background_image=cv2.cvtColor(background_image, cv2.COLOR_RGB2BGR) if background_image is not None else None,
68
+ background_prompt=background_prompt,
69
+ seed=seed,
70
+ )
71
+
72
+ if result.status_code == 200:
73
+ return cv2.cvtColor(result.image, cv2.COLOR_BGR2RGB), f"<h3>Success</h3><p>Seed: {result.seed}</p>"
74
+ else:
75
+ error_message = f"<h3>Error {result.status_code}</h3>"
76
+
77
+ if result.error_details is not None:
78
+ error_message += f"<p>{result.error_details}</p>"
79
+
80
+ return None, error_message
81
+
82
+
83
+ with gr.Blocks(theme=gr.themes.Soft(), delete_cache=(3600, 3600)) as app:
84
+ gr.HTML(
85
+ f"""
86
+ <div style="width: 100%; background-color: #001537; border-radius: 10px; padding-left: 10px">
87
+ <a href="https://texelmoda.com/" target="_blank">
88
+ <img src="{get_image_base64("images/logo.png")}" title="Texel.Moda" alt="Texel.Moda" style="float: left; margin-right: 10px; margin-left: -10px; border-radius: 10px; max-height: 50px;"/>
89
+ </a>
90
+ <h1 style="margin: 0; margin-right: 10px; line-height: 50px; color: #8cecd5; text-transform: uppercase">Virtual Try-On Diffusion</h1>
91
+ </div>
92
+ <br/>
93
+ <p>
94
+ Virtual Try-On Diffusion [VTON-D] by <a href="https://texelmoda.com/" target="_blank">Texel.Moda</a> is a
95
+ custom diffusion-based pipeline for fast and flexible multi-modal virtual try-on.
96
+ Clothing, avatar and background can be specified by reference images or text prompts allowing for clothing
97
+ transfer, avatar replacement, fashion image generation and other virtual try-on related tasks.
98
+ """
99
+ )
100
+
101
+ if SHOW_RAPIDAPI_LINK:
102
+ gr.Button(
103
+ value="Check out the API @ RapidAPI.com",
104
+ link="https://rapidapi.com/texelmoda-texelmoda-apis/api/try-on-diffusion",
105
+ icon="https://files.readme.io/9336831-small-rapid-logo-favicon.png",
106
+ )
107
+
108
+ gr.HTML(
109
+ """
110
+ <center>
111
+ <a href="https://huggingface.co/spaces/texelmoda/try-on-diffusion/blob/main/docs/API.md">API Documentation</a>
112
+ </center>
113
+ """
114
+ )
115
+
116
+ gr.HTML("</p>")
117
+
118
+ with gr.Row():
119
+ with gr.Column():
120
+ gr.HTML(
121
+ """
122
+ <h2>Clothing</h2>
123
+ <p>
124
+ Clothing may be specified with a reference image or a text prompt.
125
+ For more exotic use cases image and prompt can be also used together.
126
+ If both image and prompt are empty the model will generate random clothing.
127
+ <br/><br/>
128
+ </p>
129
+ """
130
+ )
131
+
132
+ with gr.Tab("Image"):
133
+ clothing_image = gr.Image(label="Clothing Image", sources=["upload"], type="numpy")
134
+
135
+ clothing_image_examples = gr.Examples(
136
+ inputs=clothing_image, examples_per_page=18, examples=get_examples("clothing")
137
+ )
138
+
139
+ with gr.Tab("Prompt"):
140
+ clothing_prompt = gr.TextArea(
141
+ label="Clothing Prompt",
142
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
143
+ )
144
+
145
+ clothing_prompt_examples = gr.Examples(
146
+ inputs=clothing_prompt,
147
+ examples_per_page=8,
148
+ examples=[
149
+ "a sheer blue sleeveless mini dress",
150
+ "a beige woolen sweater and white pleated skirt",
151
+ "a black leather jacket and dark blue slim-fit jeans",
152
+ "a floral pattern blouse and leggings",
153
+ "a paisley pattern purple shirt and beige chinos",
154
+ "a striped white and blue polo shirt and blue jeans",
155
+ "a colorful t-shirt and black shorts",
156
+ "a checked pattern shirt and dark blue cargo pants",
157
+ ],
158
+ )
159
+
160
+ with gr.Column():
161
+ gr.HTML(
162
+ """
163
+ <h2>Avatar</h2>
164
+ <p>
165
+ Avatar may be specified with a subject photo or a text prompt.
166
+ Latter can be used, for example, to replace person while preserving clothing.
167
+ For more exotic use cases image and prompt can be also used together.
168
+ If both image and prompt are empty the model will generate random avatars.
169
+ </p>
170
+ """
171
+ )
172
+
173
+ with gr.Tab("Image"):
174
+ avatar_image = gr.Image(label="Avatar Image", sources=["upload"], type="numpy")
175
+
176
+ avatar_image_examples = gr.Examples(
177
+ inputs=avatar_image,
178
+ examples_per_page=18,
179
+ examples=get_examples("avatar"),
180
+ )
181
+
182
+ with gr.Tab("Prompt"):
183
+ avatar_prompt = gr.TextArea(
184
+ label="Avatar Prompt",
185
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
186
+ )
187
+
188
+ avatar_prompt_examples = gr.Examples(
189
+ inputs=avatar_prompt,
190
+ examples_per_page=8,
191
+ examples=[
192
+ "a beautiful blond girl with long hair",
193
+ "a cute redhead girl with freckles",
194
+ "a plus size female model wearing sunglasses",
195
+ "a woman with dark hair and blue eyes",
196
+ "a fit man with dark beard and blue eyes",
197
+ "a young blond man posing for a photo",
198
+ "a gentleman with beard and mustache",
199
+ "a plus size man walking",
200
+ ],
201
+ )
202
+
203
+ avatar_sex = gr.Dropdown(
204
+ label="Avatar Sex",
205
+ choices=[("Auto", ""), ("Male", "male"), ("Female", "female")],
206
+ value="",
207
+ info="Avatar sex selector can be used to enforce a specific sex of the avatar.",
208
+ )
209
+
210
+ with gr.Column():
211
+ gr.HTML(
212
+ """
213
+ <h2>Background</h2>
214
+ <p>
215
+ Replacing the background is optional.
216
+ Resulting background may be specified with a reference image or a text prompt.
217
+ If omitted the original avatar background will be preserved.
218
+ <br/><br/><br/>
219
+ </p>
220
+ """
221
+ )
222
+
223
+ with gr.Tab("Image"):
224
+ background_image = gr.Image(label="Background Image", sources=["upload"], type="numpy")
225
+
226
+ background_image_examples = gr.Examples(
227
+ inputs=background_image, examples_per_page=18, examples=get_examples("background")
228
+ )
229
+
230
+ with gr.Tab("Prompt"):
231
+ background_prompt = gr.TextArea(
232
+ label="Background Prompt",
233
+ info='Compel weighting <a href="https://github.com/damian0815/compel/blob/main/doc/syntax.md">syntax</a> is supported.',
234
+ )
235
+
236
+ background_prompt_examples = gr.Examples(
237
+ inputs=background_prompt,
238
+ examples_per_page=8,
239
+ examples=[
240
+ "in an autumn park",
241
+ "in front of a brick wall",
242
+ "near an old tree",
243
+ "on a busy city street",
244
+ "in front of a staircase",
245
+ "on an ocean beach with palm trees",
246
+ "in a shopping mall",
247
+ "in a modern office",
248
+ ],
249
+ )
250
+
251
+ with gr.Column():
252
+ gr.HTML(
253
+ """
254
+ <h2>Generation</h2>
255
+ """
256
+ )
257
+
258
+ seed = gr.Number(
259
+ label="Seed",
260
+ value=-1,
261
+ minimum=-1,
262
+ info="Seed used for generation, specify -1 for random seed for each generation.",
263
+ )
264
+
265
+ generate_button = gr.Button(value="Generate", variant="primary")
266
+
267
+ result_image = gr.Image(label="Result", show_share_button=False, format="jpeg")
268
+ result_details = gr.HTML(label="Details")
269
+
270
+ generate_button.click(
271
+ fn=try_on,
272
+ inputs=[
273
+ clothing_image,
274
+ clothing_prompt,
275
+ avatar_image,
276
+ avatar_prompt,
277
+ avatar_sex,
278
+ background_image,
279
+ background_prompt,
280
+ seed,
281
+ ],
282
+ outputs=[result_image, result_details],
283
+ api_name=False,
284
+ concurrency_limit=CONCURRENCY_LIMIT,
285
+ )
286
+
287
+ app.title = "Virtual Try-On Diffusion by Texel.Moda"
288
+
289
+
290
+ if __name__ == "__main__":
291
+ app.queue(api_open=False).launch(show_api=False, ssr_mode=False)