tonyassi commited on
Commit
63a4bcf
Β·
verified Β·
1 Parent(s): 4d6e9ae

Upload 9 files

Browse files
README.md CHANGED
@@ -1,12 +1,14 @@
1
  ---
2
- title: Clothing Swap
3
- emoji: πŸ’»
4
- colorFrom: blue
5
  colorTo: pink
6
  sdk: gradio
7
- sdk_version: 5.15.0
8
  app_file: app.py
9
- pinned: false
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Virtual Try On Pro
3
+ emoji: πŸ‘—πŸ§πŸΌβ€β™€οΈ
4
+ colorFrom: pink
5
  colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 4.44.1
8
  app_file: app.py
9
+ pinned: true
10
+ short_description: Free virtual clothing try-on and API
11
+ disable_embedding: false
12
  ---
13
 
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ import os
2
+
3
+ exec(os.environ.get('APP'))
db.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ import os
2
+
3
+ exec(os.environ.get('DB'))
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ imagekitio
2
+ sendgrid
3
+ flask
static/.DS_Store ADDED
Binary file (6.15 kB). View file
 
static/spinner.gif ADDED
static/styles.css ADDED
@@ -0,0 +1,320 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* General Reset */
2
+ * {
3
+ margin: 0;
4
+ padding: 10px 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ body {
9
+ font-family: Arial, sans-serif;
10
+ background-color: #f8f8f8;
11
+ color: #333;
12
+ margin: 0;
13
+ display: flex;
14
+ justify-content: center; /* Center horizontally */
15
+ align-items: flex-start; /* Align to the top */
16
+ min-height: 100vh;
17
+ overflow-y: auto; /* Allow scrolling when content overflows */
18
+ }
19
+ .container {
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center; /* Center horizontally */
23
+ justify-content: flex-start; /* Align to the top */
24
+ width: 100%;
25
+ max-width: 1000px;
26
+ padding: 20px;
27
+ /* margin: 20px 20px; */ /* Add vertical margin */
28
+ box-sizing: border-box;
29
+ }
30
+
31
+ /* Title */
32
+ .title {
33
+ font-size: 2.5rem;
34
+ font-weight: bold;
35
+ color: #333;
36
+ text-align: center;
37
+ width: 100%;
38
+ }
39
+
40
+ /* Key Input and Get Key Button */
41
+ .key-container {
42
+ display: flex;
43
+ align-items: center;
44
+ gap: 10px;
45
+ /* margin-bottom: 20px; */
46
+ }
47
+
48
+ .key-input {
49
+ width: 300px;
50
+ padding: 10px;
51
+ border: 2px solid #ccc;
52
+ border-radius: 5px;
53
+ font-size: 1rem;
54
+ text-align: center;
55
+ }
56
+
57
+ .get-key-btn {
58
+ padding: 10px 20px;
59
+ background-color: #28a745;
60
+ color: #fff;
61
+ border: none;
62
+ border-radius: 5px;
63
+ cursor: pointer;
64
+ }
65
+
66
+ .get-key-btn:hover {
67
+ background-color: #218838;
68
+ }
69
+
70
+ /* Form Layout */
71
+ form {
72
+ width: 100%;
73
+ }
74
+
75
+ .input-container {
76
+ display: flex;
77
+ flex-wrap: wrap;
78
+ justify-content: flex-start;
79
+ align-items: flex-start;
80
+ gap: 20px;
81
+ width: 100%;
82
+ }
83
+
84
+ /* Drag and Drop Box */
85
+ .drag-drop-box {
86
+ border: 2px dashed #aaa;
87
+ border-radius: 10px;
88
+ width: 300px;
89
+ height: 400px;
90
+ position: relative;
91
+ background-color: #f9f9f9;
92
+ overflow: hidden;
93
+ cursor: pointer;
94
+ transition: background-color 0.3s ease, border-color 0.3s ease;
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: center;
98
+ }
99
+
100
+ .drag-drop-box p {
101
+ position: absolute;
102
+ margin: 0;
103
+ color: #666;
104
+ pointer-events: none;
105
+ text-align: center;
106
+ width: 80%;
107
+ }
108
+
109
+ .drag-drop-box input[type="file"] {
110
+ position: absolute;
111
+ opacity: 0;
112
+ width: 100%;
113
+ height: 100%;
114
+ cursor: pointer;
115
+ }
116
+
117
+ .drag-drop-box.drag-over {
118
+ background-color: #e8f4ff;
119
+ border-color: #007bff;
120
+ }
121
+
122
+ /* Image Preview */
123
+ .preview {
124
+ max-width: 100%;
125
+ max-height: 100%;
126
+ object-fit: contain;
127
+ position: absolute;
128
+ border-radius: 5px;
129
+ }
130
+
131
+ /* Output Container */
132
+ .output-container {
133
+ display: flex;
134
+ flex-direction: column;
135
+ align-items: center;
136
+ gap: 10px;
137
+ width: 300px;
138
+ }
139
+
140
+ .output-box {
141
+ border: 2px solid #ccc;
142
+ border-radius: 10px;
143
+ width: 300px;
144
+ height: 400px;
145
+ background-color: #fff;
146
+ overflow: hidden;
147
+ position: relative;
148
+ display: flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ }
152
+
153
+ .output-box img {
154
+ max-width: 100%;
155
+ max-height: 100%;
156
+ object-fit: contain;
157
+ border-radius: 5px;
158
+ }
159
+
160
+ /* Generate Button */
161
+ .generate-btn {
162
+ width: 100%;
163
+ padding: 10px;
164
+ background-color: #007bff;
165
+ color: #fff;
166
+ border: none;
167
+ border-radius: 5px;
168
+ font-size: 16px;
169
+ cursor: pointer;
170
+ }
171
+
172
+ .generate-btn:hover {
173
+ background-color: #0056b3;
174
+ }
175
+
176
+ /* Popup Styles */
177
+ .popup {
178
+ display: none;
179
+ position: fixed;
180
+ z-index: 1000;
181
+ left: 0;
182
+ top: 0;
183
+ width: 100%;
184
+ height: 100%;
185
+ overflow: auto;
186
+ background-color: rgba(0,0,0,0.5);
187
+ }
188
+
189
+ .popup-content {
190
+ background-color: #fff;
191
+ margin: 10% auto;
192
+ padding: 20px;
193
+ border: 1px solid #888;
194
+ width: 90%;
195
+ max-width: 400px;
196
+ text-align: center;
197
+ position: relative;
198
+ border-radius: 10px;
199
+
200
+ display: flex;
201
+ flex-direction: column;
202
+ align-items: center; /* Center content horizontally */
203
+ justify-content: center; /* Center content vertically (optional) */
204
+ }
205
+
206
+ .close-btn {
207
+ position: absolute;
208
+ top: 10px;
209
+ right: 15px;
210
+ color: #aaa;
211
+ font-size: 28px;
212
+ font-weight: bold;
213
+ cursor: pointer;
214
+ }
215
+
216
+ .close-btn:hover,
217
+ .close-btn:focus {
218
+ color: black;
219
+ text-decoration: none;
220
+ cursor: pointer;
221
+ }
222
+
223
+ .popup-input {
224
+ width: 80%;
225
+ padding: 10px;
226
+ margin-top: 15px;
227
+ margin-bottom: 15px;
228
+ border: 2px solid #ccc;
229
+ border-radius: 5px;
230
+ font-size: 1rem;
231
+ }
232
+
233
+ .submit-btn {
234
+ padding: 10px 20px;
235
+ background-color: #28a745;
236
+ color: #fff;
237
+ border: none;
238
+ border-radius: 5px;
239
+ cursor: pointer;
240
+ }
241
+
242
+ .submit-btn:hover {
243
+ background-color: #218838;
244
+ }
245
+ .remove-btn {
246
+ position: absolute;
247
+ top: 5px;
248
+ right: 5px;
249
+ background-color: gray;
250
+ color: white;
251
+ border: none;
252
+ border-radius: 50%;
253
+ width: 20px;
254
+ height: 20px;
255
+ text-align: center;
256
+ font-size: 16px;
257
+ cursor: pointer;
258
+ line-height: 20px;
259
+ display: flex;
260
+ align-items: center;
261
+ justify-content: center;
262
+ }
263
+ .box-wrapper {
264
+ display: flex;
265
+ flex-direction: column;
266
+ align-items: center;
267
+ width: 100%; /* Ensure full width on smaller screens */
268
+ max-width: 300px; /* Limit the maximum width for better proportions */
269
+ min-width: 250px; /* Prevent boxes from becoming too narrow */
270
+ margin: 10px auto; /* Center the box and add spacing */
271
+ }
272
+
273
+
274
+
275
+ .image-container {
276
+ display: flex;
277
+ flex-direction: row; /* Force row layout on desktop */
278
+ justify-content: center;
279
+ border: 2px solid #aaa;
280
+ /* padding: 10px; */
281
+ border-radius: 10px;
282
+ gap: 10px;
283
+ max-width: 100%;
284
+ margin: 10px;
285
+ }
286
+
287
+ .image-container img {
288
+ width: 30%; /* Each image takes 30% of the container width */
289
+ height: auto;
290
+ box-sizing: border-box;
291
+ }
292
+
293
+ @media (max-width: 768px) {
294
+ .image-container {
295
+ flex-direction: column; /* Stack images vertically on mobile */
296
+ align-items: center;
297
+ }
298
+
299
+ .image-container img {
300
+ width: 100%; /* Full width for each image on mobile */
301
+ }
302
+ }
303
+
304
+
305
+
306
+
307
+
308
+ /* Responsive Layout */
309
+ @media (max-width: 768px) {
310
+ .input-container {
311
+ flex-direction: column;
312
+ align-items: center;
313
+ gap: 20px;
314
+ }
315
+
316
+ .drag-drop-box,
317
+ .output-box {
318
+ width: 100%;
319
+ }
320
+ }
static/watermark1.1.png ADDED
templates/index.html ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Virtual Try-On</title>
6
+ <link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <script>
9
+ // Handle the popup window
10
+ function openPopup() {
11
+ document.getElementById("popup").style.display = "block";
12
+ document.getElementById("emailInput").style.display = "block";
13
+ document.getElementById("submitBtn").style.display = "block";
14
+ document.getElementById("popupMessage").innerText = "Get a free trial key sent to your email";
15
+ }
16
+
17
+ function closePopup() {
18
+ document.getElementById("popup").style.display = "none";
19
+ document.getElementById("emailInput").value = "";
20
+ document.getElementById("popupMessage").innerText = "Get a free trial key sent to your email";
21
+ }
22
+
23
+ // Handle email submission
24
+ function submitEmail() {
25
+ const emailInput = document.getElementById("emailInput").value;
26
+
27
+ fetch("/send_key", {
28
+ method: "POST",
29
+ headers: { "Content-Type": "application/json" },
30
+ body: JSON.stringify({ email: emailInput })
31
+ })
32
+ .then(response => response.json())
33
+ .then(data => {
34
+ document.getElementById("popupMessage").innerText = data.message;
35
+ document.getElementById("emailInput").style.display = "none";
36
+ document.getElementById("submitBtn").style.display = "none";
37
+ })
38
+ .catch(err => alert("Error: " + err));
39
+ }
40
+
41
+ // Handle drag-and-drop and previews
42
+ function enableImagePreview(boxId, inputId, previewId, textId, removeButtonId) {
43
+ const box = document.getElementById(boxId);
44
+ const input = document.getElementById(inputId);
45
+ const preview = document.getElementById(previewId);
46
+ const text = document.getElementById(textId);
47
+
48
+ box.addEventListener("dragover", (e) => {
49
+ e.preventDefault();
50
+ box.classList.add("drag-over");
51
+ });
52
+
53
+ box.addEventListener("dragleave", () => box.classList.remove("drag-over"));
54
+
55
+ box.addEventListener("drop", (e) => {
56
+ e.preventDefault();
57
+ box.classList.remove("drag-over");
58
+ const file = e.dataTransfer.files[0];
59
+ input.files = e.dataTransfer.files;
60
+ showPreview(file, preview, text, removeButtonId);
61
+ });
62
+
63
+ input.addEventListener("change", () => {
64
+ if (input.files.length > 0) {
65
+ showPreview(input.files[0], preview, text, removeButtonId);
66
+ }
67
+ });
68
+ }
69
+
70
+ function showPreview(file, previewElement, textElement, removeButton) {
71
+ const reader = new FileReader();
72
+ reader.onload = (e) => {
73
+ previewElement.src = e.target.result;
74
+ previewElement.style.display = "block";
75
+ textElement.style.display = "none";
76
+ document.getElementById(removeButton).style.display = "flex";
77
+ };
78
+ reader.readAsDataURL(file);
79
+ }
80
+
81
+ function removeImage(inputId, previewId, textId, removeButtonId) {
82
+ const input = document.getElementById(inputId);
83
+ const preview = document.getElementById(previewId);
84
+ const text = document.getElementById(textId);
85
+ const removeButton = document.getElementById(removeButtonId);
86
+
87
+ input.value = ""; // Clear the file input
88
+ preview.src = ""; // Clear the preview image
89
+ preview.style.display = "none";
90
+ text.style.display = "block";
91
+ removeButton.style.display = "none";
92
+ }
93
+
94
+ // Submit form with AJAX
95
+ function submitForm(event) {
96
+ event.preventDefault();
97
+ const formData = new FormData(document.getElementById("imageForm"));
98
+
99
+ document.getElementById("outputImage").style.display = "none";
100
+
101
+ const spinner = document.getElementById("spinner");
102
+ spinner.style.display = "block"; // Unhide the spinner
103
+
104
+ // Get the key input value and add it to the form data
105
+ const keyInput = document.querySelector('.key-input').value;
106
+ formData.append('key', keyInput);
107
+
108
+ fetch("/process", {
109
+ method: "POST",
110
+ body: formData
111
+ })
112
+ .then(response => response.json())
113
+ .then(data => {
114
+ if (data.output_image) {
115
+ spinner.style.display = "none";
116
+ document.getElementById("outputImage").src = data.output_image;
117
+ document.getElementById("outputImage").style.display = "block";
118
+ } else if (data.error) {
119
+ alert(data.error);
120
+ }
121
+ })
122
+ .catch(err => {
123
+ spinner.style.display = "none"; // Hide the spinner on error
124
+ alert("Error: " + err);
125
+ })
126
+ .finally(() => {
127
+ spinner.style.display = "none"; // Ensure spinner hides after completion
128
+ });
129
+ }
130
+
131
+
132
+ window.onload = () => {
133
+ enableImagePreview("box1", "input1", "preview1", "text1", "remove1");
134
+ enableImagePreview("box2", "input2", "preview2", "text2", "remove2");
135
+ document.getElementById("imageForm").addEventListener("submit", submitForm);
136
+ };
137
+ </script>
138
+ </head>
139
+ <body>
140
+ <div class="container">
141
+ <!-- Title -->
142
+ <h1 class="title">Virtual Try-On</h1>
143
+
144
+ <p> Check out the <a href="https://vto.face-swap.co/" target="_blank">Virtual Try-On API</a>. Reach out to <a href="mailto:[email protected]">[email protected]</a> for inquiries. </p>
145
+
146
+ <!-- Key Input -->
147
+ <div class="key-container">
148
+ <input type="text" class="key-input" placeholder="Input your key here">
149
+ </div>
150
+ <button type="button" class="get-key-btn" onclick="openPopup()">Get a free key</button>
151
+
152
+
153
+ <!-- Form -->
154
+ <form id="imageForm">
155
+ <div class="input-container">
156
+
157
+ <div class="box-wrapper">
158
+ <p>Person</p>
159
+ <div class="drag-drop-box" id="box1">
160
+ <p id="text1">Person/Model Image</p>
161
+ <input type="file" id="input1" name="image1" accept="image/*" required>
162
+ <img id="preview1" class="preview" style="display: none;">
163
+ <span class="remove-btn" id="remove1" style="display: none;" onclick="removeImage('input1', 'preview1', 'text1', 'remove1')">Γ—</span>
164
+ </div>
165
+ </div>
166
+
167
+ <!-- Input Box 2 -->
168
+ <div class="box-wrapper">
169
+ <p>Garment</p>
170
+ <div class="drag-drop-box" id="box2">
171
+ <p id="text2">Garment Image</p>
172
+ <input type="file" id="input2" name="image2" accept="image/*" required>
173
+ <img id="preview2" class="preview" style="display: none;">
174
+ <span class="remove-btn" id="remove2" style="display: none;" onclick="removeImage('input2', 'preview2', 'text2', 'remove2')">Γ—</span>
175
+ </div>
176
+ </div>
177
+
178
+
179
+ <!-- Output Container -->
180
+ <div class="box-wrapper">
181
+ <p>Result</p>
182
+ <div class="output-container">
183
+ <div class="output-box">
184
+ <img id="spinner" src="{{ url_for('static', filename='spinner.gif') }}" style="display: none;" alt="Loading...">
185
+ <img id="outputImage" style="display: none;" alt="Output Image">
186
+ </div>
187
+ <!-- Generate Button -->
188
+ <button type="submit" class="generate-btn">Generate (~20 sec)</button>
189
+ </div>
190
+ </div>
191
+ </div>
192
+ </form>
193
+ <div class="image-container">
194
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/kim1.jpg" alt="Image 1">
195
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/kim2.jpg" alt="Image 2">
196
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro-Dev/resolve/main/examples/kim3.jpg" alt="Image 3">
197
+ </div>
198
+ <div class="image-container">
199
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/meg1.jpg" alt="Image 1">
200
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/meg2.jpg" alt="Image 2">
201
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/meg3.jpg" alt="Image 3">
202
+ </div>
203
+ <div class="image-container">
204
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/bella1.jpg" alt="Image 1">
205
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/bella2.jpg" alt="Image 2">
206
+ <img src="https://huggingface.co/spaces/tonyassi/Virtual-Try-On-Pro/resolve/main/examples/bella3.jpg" alt="Image 3">
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Popup Window -->
211
+ <div id="popup" class="popup">
212
+ <div class="popup-content">
213
+ <span class="close-btn" onclick="closePopup()">Γ—</span>
214
+ <p id="popupMessage">Get a free trial key sent to your gmail</p>
215
+ <input type="email" id="emailInput" class="popup-input" placeholder="Email">
216
+ <button id="submitBtn" type="button" class="submit-btn" onclick="submitEmail()">Submit</button>
217
+ </div>
218
+ </div>
219
+
220
+
221
+
222
+ </body>
223
+ </html>