Abhlash commited on
Commit
bca57e9
1 Parent(s): a762474

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +389 -0
app.py ADDED
@@ -0,0 +1,389 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ from PIL import Image
4
+ import numpy as np
5
+ from image_generation import generate_image
6
+ from virtual_tryon import (
7
+ apply_virtual_tryon,
8
+ VALID_CLOTH_TYPES,
9
+ VALID_IMAGE_SIZES,
10
+ DEFAULT_IMAGE_SIZE,
11
+ DEFAULT_NUM_STEPS,
12
+ DEFAULT_GUIDANCE_SCALE,
13
+ DEFAULT_SEED
14
+ )
15
+ import io
16
+ import urllib3
17
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
18
+
19
+ # Set page config
20
+ st.set_page_config(
21
+ page_title="Virtual Try-On",
22
+ layout="wide",
23
+ initial_sidebar_state="expanded"
24
+ )
25
+
26
+ # Constants
27
+ MAX_SEED = 2147483647
28
+ DEFAULT_LORA_KEYWORD = "OhwxAvani Mehta"
29
+ EXAMPLE_PROMPTS = [
30
+ "fashion product showcase closeup of a luxury red evening dress, studio lighting",
31
+ "wide shot fashion model wearing designer denim jacket, urban street background",
32
+ "closeup product photography of handcrafted leather handbag, neutral background",
33
+ "full body fashion showcase of summer collection dress, beach setting",
34
+ "detailed closeup of haute couture embroidered blouse, professional studio setup",
35
+ "wide angle fashion editorial of winter coat ensemble, city backdrop",
36
+ "product closeup of designer sneakers, minimalist background",
37
+ "editorial wide shot of evening wear collection, elegant interior setting"
38
+ ]
39
+
40
+ def main():
41
+ st.title("Virtual Try-On System")
42
+ st.markdown("Upload images or generate new ones to try on different clothing items!")
43
+
44
+ # Sidebar for API keys and LoRA settings
45
+ with st.sidebar:
46
+ st.header("API Configuration")
47
+ replicate_api = st.text_input("Replicate API Key", type="password")
48
+
49
+ # Kling API Configuration
50
+ st.subheader("Kling API Configuration")
51
+ kling_access_key = st.text_input("Kling Access Key", type="password")
52
+ kling_secret_key = st.text_input("Kling Secret Key", type="password")
53
+
54
+ st.header("Generation Settings")
55
+ use_lora = st.checkbox("Use LoRA", value=True)
56
+
57
+ if use_lora:
58
+ custom_lora = st.text_input(
59
+ "Custom LoRA URL",
60
+ value="https://huggingface.co/0Learn/loratest/resolve/main/lora.safetensors"
61
+ )
62
+ use_keyword = st.checkbox(
63
+ "Add style keyword to prompts",
64
+ value=True,
65
+ help="Automatically add a style keyword to your prompts"
66
+ )
67
+ if use_keyword:
68
+ custom_keyword = st.text_input(
69
+ "Custom Style Keyword",
70
+ value=DEFAULT_LORA_KEYWORD,
71
+ help="This keyword will be added to your prompts"
72
+ )
73
+
74
+ # Add a tabs section for different functionalities
75
+ tab1, tab2 = st.tabs(["Generate Images", "Virtual Try-On"])
76
+
77
+ with tab1:
78
+ st.header("Image Generation")
79
+
80
+ col1, col2 = st.columns(2)
81
+
82
+ with col1:
83
+ st.subheader("Generation Settings")
84
+ prompt = st.text_area(
85
+ "Generation Prompt",
86
+ value=EXAMPLE_PROMPTS[0],
87
+ height=100,
88
+ help="Describe the image you want to generate"
89
+ )
90
+
91
+ # Example prompts
92
+ with st.expander("Example Prompts"):
93
+ for example in EXAMPLE_PROMPTS:
94
+ if st.button(example[:50] + "...", key=example):
95
+ prompt = example
96
+ st.session_state.current_prompt = example
97
+
98
+ # Advanced settings
99
+ with st.expander("Advanced Settings", expanded=True):
100
+ num_steps = st.slider(
101
+ "Number of Steps",
102
+ min_value=20,
103
+ max_value=50,
104
+ value=DEFAULT_NUM_STEPS,
105
+ help="More steps = better quality but slower"
106
+ )
107
+
108
+ guidance = st.slider(
109
+ "Guidance Scale",
110
+ min_value=1.0,
111
+ max_value=20.0,
112
+ value=DEFAULT_GUIDANCE_SCALE,
113
+ help="How closely to follow the prompt"
114
+ )
115
+
116
+ aspect = st.radio(
117
+ "Aspect Ratio",
118
+ ["1:1", "16:9", "3:2", "2:3", "4:5", "5:4"],
119
+ help="Select the aspect ratio for the generated image"
120
+ )
121
+
122
+ negative_prompt = st.text_area(
123
+ "Negative Prompt",
124
+ value="ugly, blurry, low quality, distorted, deformed",
125
+ help="What to avoid in the generation"
126
+ )
127
+
128
+ with col2:
129
+ st.subheader("Generated Image")
130
+ if st.button("Generate Image", type="primary"):
131
+ if not replicate_api:
132
+ st.error("Please provide your Replicate API key in the sidebar!")
133
+ else:
134
+ with st.spinner("Generating image..."):
135
+ # Add LoRA and keyword if enabled
136
+ final_prompt = prompt
137
+ if use_lora and use_keyword and 'custom_keyword' in locals():
138
+ final_prompt = f"{custom_keyword} {prompt}"
139
+
140
+ result_image, status = generate_image(
141
+ final_prompt,
142
+ num_steps=num_steps,
143
+ guidance_scale=guidance,
144
+ aspect_ratio=aspect,
145
+ replicate_api_key=replicate_api,
146
+ lora_url=custom_lora if use_lora else None,
147
+ negative_prompt=negative_prompt
148
+ )
149
+
150
+ if result_image:
151
+ st.session_state.generated_image = result_image
152
+ st.image(result_image, caption="Generated Image", use_column_width=True)
153
+
154
+ # Add buttons to use the generated image
155
+ col1, col2 = st.columns(2)
156
+ with col1:
157
+ if st.button("Use as Person Image"):
158
+ st.session_state.person_img = result_image
159
+ st.success("Set as person image!")
160
+ with col2:
161
+ if st.button("Use as Garment Image"):
162
+ st.session_state.garment_img = result_image
163
+ st.success("Set as garment image!")
164
+
165
+ # Add download button
166
+ buf = io.BytesIO()
167
+ result_image.save(buf, format="PNG")
168
+ st.download_button(
169
+ label="Download Image",
170
+ data=buf.getvalue(),
171
+ file_name="generated_image.png",
172
+ mime="image/png"
173
+ )
174
+ else:
175
+ st.error(status)
176
+
177
+ # Display history of generated images
178
+ if 'generated_images' not in st.session_state:
179
+ st.session_state.generated_images = []
180
+
181
+ if 'generated_image' in st.session_state:
182
+ with st.expander("Generation History"):
183
+ st.session_state.generated_images.append(st.session_state.generated_image)
184
+ for idx, img in enumerate(reversed(st.session_state.generated_images[-5:])):
185
+ st.image(img, caption=f"Generated Image {len(st.session_state.generated_images)-idx}",
186
+ use_column_width=True)
187
+
188
+ with tab2:
189
+ # Move the existing three columns layout here
190
+ col_left, col_mid, col_right = st.columns(3)
191
+
192
+ with col_left:
193
+ st.header("Person Image")
194
+ upload_method = st.radio(
195
+ "Choose input method",
196
+ ["Upload Image", "Generate Image"],
197
+ key="person_method"
198
+ )
199
+
200
+ if upload_method == "Upload Image":
201
+ preview_container = st.empty()
202
+
203
+ person_image = st.file_uploader(
204
+ "Upload person image",
205
+ type=['png', 'jpg', 'jpeg'],
206
+ key="person_upload",
207
+ help="Upload a clear full-body photo of the person"
208
+ )
209
+
210
+ if person_image is not None:
211
+ img = Image.open(person_image)
212
+
213
+ with st.expander("Image Settings"):
214
+ resize = st.checkbox("Resize Image", value=True)
215
+ if resize:
216
+ max_size = st.slider("Max Image Size", 256, 1024, 512)
217
+ aspect = float(img.size[0]) / float(img.size[1])
218
+ if aspect > 1:
219
+ new_size = (max_size, int(max_size / aspect))
220
+ else:
221
+ new_size = (int(max_size * aspect), max_size)
222
+ img = img.resize(new_size, Image.Resampling.LANCZOS)
223
+
224
+ preview_container.image(img, caption="Uploaded Person Image", use_column_width=True)
225
+ st.session_state.person_img = img
226
+ else:
227
+ prompt = st.text_area(
228
+ "Generation Prompt",
229
+ value=EXAMPLE_PROMPTS[0],
230
+ height=100
231
+ )
232
+
233
+ # Example prompts section
234
+ if st.button("Show Example Prompts"):
235
+ selected_prompt = st.selectbox(
236
+ "Select an example prompt",
237
+ EXAMPLE_PROMPTS
238
+ )
239
+ if selected_prompt:
240
+ prompt = st.text_area(
241
+ "Generation Prompt",
242
+ value=selected_prompt,
243
+ height=100,
244
+ key="selected_prompt"
245
+ )
246
+
247
+ with st.expander("Generation Settings"):
248
+ num_steps = st.slider("Steps", 20, 50, DEFAULT_NUM_STEPS)
249
+ guidance = st.slider("Guidance Scale", 1.0, 20.0, DEFAULT_GUIDANCE_SCALE)
250
+ aspect = st.radio(
251
+ "Aspect Ratio",
252
+ ["1:1", "16:9", "3:2", "2:3", "4:5", "5:4"],
253
+ help="Select the aspect ratio for the generated image"
254
+ )
255
+
256
+ if st.button("Generate Person Image"):
257
+ with st.spinner("Generating image..."):
258
+ final_prompt = prompt
259
+ if use_lora and use_keyword and 'custom_keyword' in locals():
260
+ final_prompt = f"{custom_keyword} {prompt}"
261
+
262
+ result_image, status = generate_image(
263
+ final_prompt,
264
+ num_steps=num_steps,
265
+ guidance_scale=guidance,
266
+ aspect_ratio=aspect,
267
+ replicate_api_key=replicate_api,
268
+ lora_url=custom_lora if use_lora else None
269
+ )
270
+
271
+ if result_image:
272
+ st.session_state.person_img = result_image
273
+ st.image(result_image, caption="Generated Person Image")
274
+ else:
275
+ st.error(status)
276
+
277
+ with col_mid:
278
+ st.header("Garment Image")
279
+ upload_method = st.radio(
280
+ "Choose input method",
281
+ ["Upload Image", "Generate Image"],
282
+ key="garment_method"
283
+ )
284
+
285
+ if upload_method == "Upload Image":
286
+ preview_container = st.empty()
287
+
288
+ garment_image = st.file_uploader(
289
+ "Upload garment image",
290
+ type=['png', 'jpg', 'jpeg'],
291
+ key="garment_upload",
292
+ help="Upload a clear photo of the garment on plain background"
293
+ )
294
+
295
+ if garment_image is not None:
296
+ img = Image.open(garment_image)
297
+
298
+ with st.expander("Image Settings"):
299
+ resize = st.checkbox("Resize Image", value=True, key="garment_resize")
300
+ if resize:
301
+ max_size = st.slider("Max Image Size", 256, 1024, 512, key="garment_size")
302
+ aspect = float(img.size[0]) / float(img.size[1])
303
+ if aspect > 1:
304
+ new_size = (max_size, int(max_size / aspect))
305
+ else:
306
+ new_size = (int(max_size * aspect), max_size)
307
+ img = img.resize(new_size, Image.Resampling.LANCZOS)
308
+
309
+ preview_container.image(img, caption="Uploaded Garment Image", use_column_width=True)
310
+ st.session_state.garment_img = img
311
+ else:
312
+ prompt = st.text_area(
313
+ "Generation Prompt",
314
+ value=EXAMPLE_PROMPTS[0],
315
+ height=100
316
+ )
317
+
318
+ with st.expander("Generation Settings"):
319
+ num_steps = st.slider("Steps", 20, 50, DEFAULT_NUM_STEPS, key="garment_steps")
320
+ guidance = st.slider("Guidance Scale", 1.0, 20.0, DEFAULT_GUIDANCE_SCALE, key="garment_guidance")
321
+ aspect = st.radio(
322
+ "Aspect Ratio",
323
+ ["1:1", "16:9", "3:2"],
324
+ key="garment_aspect"
325
+ )
326
+
327
+ if st.button("Generate Garment Image"):
328
+ with st.spinner("Generating image..."):
329
+ result_image, status = generate_image(
330
+ prompt,
331
+ num_steps=num_steps,
332
+ guidance_scale=guidance,
333
+ aspect_ratio=aspect,
334
+ replicate_api_key=replicate_api,
335
+ lora_url=custom_lora if use_lora else None
336
+ )
337
+
338
+ if result_image:
339
+ st.session_state.garment_img = result_image
340
+ st.image(result_image, caption="Generated Garment Image")
341
+ else:
342
+ st.error(status)
343
+
344
+ with col_right:
345
+ st.header("Virtual Try-On Result")
346
+
347
+ # Try-on button and result display
348
+ if st.button("Generate Try-On", type="primary"):
349
+ if not hasattr(st.session_state, 'person_img'):
350
+ st.error("Please provide a person image first!")
351
+ elif not hasattr(st.session_state, 'garment_img'):
352
+ st.error("Please provide a garment image first!")
353
+ elif not kling_access_key or not kling_secret_key:
354
+ st.error("Please provide both Kling Access Key and Secret Key!")
355
+ else:
356
+ with st.spinner("Generating try-on image..."):
357
+ result_image, status = apply_virtual_tryon(
358
+ st.session_state.person_img,
359
+ st.session_state.garment_img,
360
+ kling_access_key,
361
+ kling_secret_key
362
+ )
363
+
364
+ if result_image:
365
+ st.session_state.result_image = result_image
366
+ st.success("Try-on completed successfully!")
367
+
368
+ # Add download button for the result
369
+ buf = io.BytesIO()
370
+ result_image.save(buf, format="PNG")
371
+ st.download_button(
372
+ label="Download Result",
373
+ data=buf.getvalue(),
374
+ file_name="tryon_result.png",
375
+ mime="image/png"
376
+ )
377
+ else:
378
+ st.error(status)
379
+
380
+ # Result display area
381
+ if 'result_image' in st.session_state:
382
+ st.image(
383
+ st.session_state.result_image,
384
+ caption="Try-on Result",
385
+ use_container_width=True
386
+ )
387
+
388
+ if __name__ == "__main__":
389
+ main()