WeShop commited on
Commit
a3aa51c
·
1 Parent(s): 104662b

WeShopAI Bad Hand Fixer

Browse files
.gitattributes CHANGED
@@ -1,3 +1,5 @@
 
 
1
  *.7z filter=lfs diff=lfs merge=lfs -text
2
  *.arrow filter=lfs diff=lfs merge=lfs -text
3
  *.bin filter=lfs diff=lfs merge=lfs -text
@@ -33,3 +35,5 @@ 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
 
 
 
1
+ .idea/
2
+ *.iml
3
  *.7z filter=lfs diff=lfs merge=lfs -text
4
  *.arrow filter=lfs diff=lfs merge=lfs -text
5
  *.bin filter=lfs diff=lfs merge=lfs -text
 
35
  *.zip filter=lfs diff=lfs merge=lfs -text
36
  *.zst filter=lfs diff=lfs merge=lfs -text
37
  *tfevents* filter=lfs diff=lfs merge=lfs -text
38
+ *.png filter=lfs diff=lfs merge=lfs -text
39
+ *.jpg filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,10 +1,10 @@
1
  ---
2
  title: WeShopAI Bad Hand Fixer
3
- emoji: 📊
4
  colorFrom: pink
5
- colorTo: red
6
  sdk: gradio
7
- sdk_version: 5.28.0
8
  app_file: app.py
9
  pinned: false
10
  license: other
 
1
  ---
2
  title: WeShopAI Bad Hand Fixer
3
+ emoji: 🖐️
4
  colorFrom: pink
5
+ colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 5.27.1
8
  app_file: app.py
9
  pinned: false
10
  license: other
app.py ADDED
@@ -0,0 +1,495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import hmac
3
+ import hashlib
4
+ import time
5
+ import os
6
+ import requests
7
+ from io import BytesIO
8
+ from PIL import Image
9
+ import uuid
10
+ import base64
11
+
12
+ example_path = os.path.join(os.path.dirname(__file__), 'assets')
13
+ clothing_list = os.listdir(os.path.join(example_path, "clothing"))
14
+ clothing_list_path = [os.path.join(example_path, "clothing", clothing) for clothing in clothing_list]
15
+
16
+ base_url = os.getenv('base_url')
17
+ upload_image_url = os.getenv('upload_image_url')
18
+ save_mask_url = os.getenv('save_mask_url')
19
+ create_save_task_url = os.getenv('create_save_task_url')
20
+ execute_task_url = os.getenv('execute_task_url')
21
+ query_task_url = os.getenv('query_task_url')
22
+ secret_key = os.getenv('secret_key')
23
+ agent_version = os.getenv('agent_version')
24
+ agent_name = os.getenv('agent_name')
25
+ app_id = os.getenv('app_id')
26
+
27
+
28
+ def parse_response(response, state='default'):
29
+ data = {}
30
+ msg = ''
31
+ if response.status_code == 200:
32
+ try:
33
+ datas = response.json()
34
+ if datas:
35
+ data = datas.get("data")
36
+ if state == 'default':
37
+ if not data:
38
+ msg = datas.get("msg")
39
+ if not msg:
40
+ msg = "Field error."
41
+ elif state == 'saveMask':
42
+ success = datas.get("success")
43
+ code = datas.get("code")
44
+ if success and code == "1001":
45
+ data = True
46
+ else:
47
+ msg = "The parsing result is empty."
48
+ except Exception as e:
49
+ msg = f"parse error: {repr(e)}."
50
+ else:
51
+ msg = f'request error.'
52
+ return data, msg
53
+
54
+
55
+ def generate_signature(key, did, timestamp):
56
+ data = f"{did}:{timestamp}{app_id}"
57
+ h = hmac.new(key.encode(), data.encode(), hashlib.sha256)
58
+ return h.hexdigest()
59
+
60
+
61
+ def url_to_image(url, ip):
62
+ headers = {
63
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
64
+ 'X-Forwarded-For': ip
65
+ }
66
+ try:
67
+ response = requests.get(url, headers=headers, timeout=30)
68
+ except:
69
+ return None
70
+ if response.status_code == 200:
71
+ img = Image.open(BytesIO(response.content))
72
+ return img
73
+ return None
74
+
75
+
76
+ def start_task(task_id, did, ip):
77
+ timestamp = str(int(time.time()))
78
+ signature = generate_signature(
79
+ key=secret_key,
80
+ did=did,
81
+ timestamp=timestamp
82
+ )
83
+ headers = {
84
+ 'Did': did,
85
+ 'X-Timestamp': timestamp,
86
+ 'X-Signature': signature,
87
+ 'X-Forwarded-For': ip,
88
+ 'X-AppId': app_id,
89
+ }
90
+ data = {
91
+ "agentVersion": agent_version,
92
+ "agentName": agent_name,
93
+ "taskId": task_id,
94
+ "runFreeAsFallback": False
95
+ }
96
+ response = requests.post(base_url + execute_task_url, json=data, headers=headers)
97
+ data, msg = parse_response(response)
98
+ return data, msg
99
+
100
+
101
+ def create_task(image_url, did, ip):
102
+ timestamp = str(int(time.time()))
103
+ signature = generate_signature(
104
+ key=secret_key,
105
+ did=did,
106
+ timestamp=timestamp
107
+ )
108
+ headers = {
109
+ 'Did': did,
110
+ 'X-Timestamp': timestamp,
111
+ 'X-Signature': signature,
112
+ 'X-Forwarded-For': ip,
113
+ 'X-AppId': app_id,
114
+ }
115
+ data = {
116
+ "agentVersion": agent_version,
117
+ "agentName": agent_name,
118
+ "image": image_url
119
+ }
120
+ response = requests.post(base_url + create_save_task_url, json=data, headers=headers)
121
+ data, msg = parse_response(response)
122
+ return data, msg
123
+
124
+
125
+ def query_task(task_id, execution_id, did, ip):
126
+ timestamp = str(int(time.time()))
127
+ signature = generate_signature(
128
+ key=secret_key,
129
+ did=did,
130
+ timestamp=timestamp
131
+ )
132
+ headers = {
133
+ 'Did': did,
134
+ 'X-Timestamp': timestamp,
135
+ 'X-Signature': signature,
136
+ 'X-Forwarded-For': ip,
137
+ 'X-AppId': app_id,
138
+ }
139
+ data = {
140
+ "agentVersion": agent_version,
141
+ "agentName": agent_name,
142
+ "taskId": task_id,
143
+ "executionId": execution_id,
144
+ }
145
+ response = requests.post(base_url + query_task_url, json=data, headers=headers)
146
+ data, msg = parse_response(response)
147
+ return data, msg
148
+
149
+
150
+ def upload_image(image, did, ip):
151
+ if image is None:
152
+ return None
153
+ image_format = image.format if image.format else "PNG"
154
+ mime_type = f"image/{image_format.lower()}"
155
+ timestamp = str(int(time.time()))
156
+ signature = generate_signature(
157
+ key=secret_key,
158
+ did=did,
159
+ timestamp=timestamp
160
+ )
161
+ with BytesIO() as m_img:
162
+ image.save(m_img, format=image_format)
163
+ m_img.seek(0)
164
+ files = {'image': (f"main_image.{image_format.lower()}", m_img, mime_type)}
165
+ headers = {
166
+ 'Did': did,
167
+ 'X-Timestamp': timestamp,
168
+ 'X-Signature': signature,
169
+ 'X-Forwarded-For': ip,
170
+ 'X-AppId': app_id,
171
+ }
172
+ response = requests.post(base_url + upload_image_url, files=files, headers=headers)
173
+ data, msg = parse_response(response)
174
+ return data, msg
175
+
176
+
177
+ def mask_image_save(task_id, mask, did, ip):
178
+ timestamp = str(int(time.time()))
179
+ signature = generate_signature(
180
+ key=secret_key,
181
+ did=did,
182
+ timestamp=timestamp
183
+ )
184
+ headers = {
185
+ 'Did': did,
186
+ 'X-Timestamp': timestamp,
187
+ 'X-Signature': signature,
188
+ 'X-Forwarded-For': ip,
189
+ 'X-AppId': app_id,
190
+ }
191
+ data = {
192
+ "taskId": task_id,
193
+ "mask": mask,
194
+ "needGreyscale": True,
195
+ }
196
+ response = requests.post(base_url + save_mask_url, json=data, headers=headers)
197
+ data, msg = parse_response(response, state='saveMask')
198
+ return data, msg
199
+
200
+
201
+ def load_description(file_path):
202
+ with open(file_path, 'r', encoding='utf-8') as file:
203
+ content = file.read()
204
+ return content
205
+
206
+
207
+ def extract_and_binarize_alpha_channel(image, threshold=10):
208
+ if image.mode in ('RGBA', 'LA') or (image.mode == 'P' and 'transparency' in image.info):
209
+ alpha = image.split()[-1]
210
+ new_image = Image.new("L", image.size)
211
+ new_image.putdata(alpha.getdata())
212
+ binary_data = [(255 if pixel >= threshold else 0) for pixel in new_image.getdata()]
213
+ new_image.putdata(binary_data)
214
+ return new_image
215
+ else:
216
+ return None
217
+
218
+
219
+ def image_to_base64(image):
220
+ buffered = BytesIO()
221
+ image.save(buffered, format="PNG")
222
+ img_base64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
223
+ return f"data:image/png;base64,{img_base64}"
224
+
225
+
226
+ def generate_image(edit_image_infos, did, request: gr.Request):
227
+ if not did:
228
+ did = str(uuid.uuid4())
229
+ if edit_image_infos is None or not isinstance(edit_image_infos, dict):
230
+ m = "Please upload the main image before generating."
231
+ return gr.Warning(m), did
232
+ main_image = None
233
+ mask_image = None
234
+ for edit_image_key, edit_image_value in edit_image_infos.items():
235
+ if edit_image_key == 'background':
236
+ if isinstance(edit_image_value, Image.Image):
237
+ main_image = edit_image_value
238
+ elif edit_image_key == 'layers':
239
+ if edit_image_value and isinstance(edit_image_value, list) and isinstance(edit_image_value[0], Image.Image):
240
+ mask_image = extract_and_binarize_alpha_channel(edit_image_value[0])
241
+ if not main_image or not mask_image:
242
+ m = "Unable to parse image data."
243
+ return gr.Warning(m), did
244
+
245
+ if all(pixel == 0 for pixel in mask_image.getdata()):
246
+ m = "Please use the brush tool to mark the areas on the image that require detailed hand retouching."
247
+ return gr.Warning(m), did
248
+
249
+ client_ip = request.client.host
250
+ x_forwarded_for = request.headers.get('x-forwarded-for')
251
+ if x_forwarded_for:
252
+ client_ip = x_forwarded_for
253
+
254
+ upload_image_data, upload_image_msg = upload_image(
255
+ image=main_image,
256
+ did=did,
257
+ ip=client_ip
258
+ )
259
+ if not upload_image_data:
260
+ return gr.Warning(upload_image_msg), did
261
+ image_url = upload_image_data.get("image")
262
+ if not image_url:
263
+ m = 'Upload image failed.'
264
+ return gr.Warning(m), did
265
+ create_task_data, create_task_msg = create_task(
266
+ image_url=image_url,
267
+ did=did,
268
+ ip=client_ip
269
+ )
270
+ if not create_task_data:
271
+ return gr.Warning(create_task_msg), did
272
+ task_id = create_task_data.get("taskId")
273
+ show_image = create_task_data.get("showImage")
274
+ if not task_id or not show_image:
275
+ m = 'Create task failed.'
276
+ return gr.Warning(m), did
277
+ mask_image_save_data, mask_image_save_msg = mask_image_save(
278
+ task_id=task_id,
279
+ mask=image_to_base64(mask_image),
280
+ did=did,
281
+ ip=client_ip
282
+ )
283
+ if not mask_image_save_data:
284
+ return gr.Warning(mask_image_save_msg), did
285
+
286
+ start_task_data, start_task_msg = start_task(
287
+ task_id=task_id,
288
+ did=did,
289
+ ip=client_ip
290
+ )
291
+ if not start_task_data:
292
+ return gr.Warning(start_task_msg), did
293
+ execution_id = start_task_data.get("executionId")
294
+ if not execution_id:
295
+ m = "The task failed to start."
296
+ return gr.Warning(m), did
297
+ start_time = int(time.time())
298
+ while True:
299
+ m = "Query task failed."
300
+ query_task_data, query_task_msg = query_task(
301
+ task_id=task_id,
302
+ execution_id=execution_id,
303
+ did=did,
304
+ ip=client_ip
305
+ )
306
+ if not query_task_data:
307
+ return gr.Warning(query_task_msg), did
308
+ executions = query_task_data.get("executions")
309
+ if not executions:
310
+ return gr.Warning(m), did
311
+ results = executions[0].get("result")
312
+ if not results:
313
+ return gr.Warning(m), did
314
+ status = results[0].get("status")
315
+ if status == "Failed":
316
+ m = "The person image does not match your garment. It is recommended to change to a different one."
317
+ return gr.Warning(m), did
318
+ elif status == "Success" or status == "Blocked":
319
+ img = results[0].get("image")
320
+ if img and str(img).strip() != "":
321
+ return url_to_image(img, ip=client_ip), did
322
+ end_time = int(time.time())
323
+ if end_time - start_time > 3600:
324
+ m = 'Query task timeout.'
325
+ return gr.Warning(m), did
326
+ time.sleep(2)
327
+
328
+
329
+ def process_show_case_image(image1, image2, result_image):
330
+ return image1, {'background': image1, 'layers': [image2], 'composite': image1}, result_image
331
+
332
+
333
+ css = """
334
+ .image-container img {
335
+ max-height: 500px;
336
+ width: auto;
337
+ }
338
+ #example-images img {
339
+ border-radius: 10px
340
+ }
341
+ #example-images .gallery-item {
342
+ border: none;
343
+ }
344
+ #example-images .container {
345
+ border: none;
346
+ }
347
+ .hide-buttons .source-selection {
348
+ display: none;
349
+ }
350
+ #example-images .gallery {
351
+ display: flex;
352
+ flex-wrap: wrap;
353
+ }
354
+ #example-images .gallery-item .container{
355
+ width: 100%;
356
+ max-width: 100%;
357
+ max-height: 100% !important;
358
+ height: 100% !important;
359
+ }
360
+ #example-images .gallery-item {
361
+ flex: 0 0 30%;
362
+ max-width: 30%;
363
+ box-sizing: border-box;
364
+ display: flex;
365
+ text-align: center;
366
+ justify-content: center;
367
+
368
+ }
369
+ .middleware {
370
+ display: none;
371
+ }
372
+ @media (max-width: 767px) {
373
+ #example-res-images th {
374
+ font-size: 12px;
375
+ word-wrap: break-word;
376
+ word-break: break-word;
377
+ white-space: normal;
378
+ overflow-wrap: break-word;
379
+ }
380
+ }
381
+
382
+ #example-res-images .tr-head {
383
+ display: grid !important;
384
+ grid-template-columns: 1fr 1fr;
385
+ }
386
+
387
+ #example-res-images .tr-head th:nth-child(1),
388
+ #example-res-images .tr-head th:nth-child(2) {
389
+ grid-column: 1;
390
+ }
391
+ #example-res-images .tr-head th:nth-child(2) {
392
+ display: none !important;
393
+ }
394
+
395
+ #example-res-images .tr-head th:last-child {
396
+ grid-column: 2;
397
+ grid-row: 1;
398
+ }
399
+
400
+ #example-res-images .tr-body {
401
+ display: grid !important;
402
+ grid-template-columns: 1fr 1fr;
403
+ position: relative;
404
+ }
405
+
406
+
407
+ #example-res-images .tr-body td:nth-child(1),
408
+ #example-res-images .tr-body td:nth-child(2) {
409
+ grid-column: 1;
410
+ grid-row: 1;
411
+ position: relative;
412
+ }
413
+
414
+ #example-res-images .tr-body td:last-child {
415
+ grid-column: 2;
416
+ grid-row: 1;
417
+ }
418
+
419
+ }
420
+ """
421
+ with gr.Blocks(css=css) as WeShop:
422
+ current_did = gr.State(value='')
423
+ gr.HTML(load_description("assets/title.html"))
424
+ with gr.Row():
425
+ with gr.Column():
426
+ gr.Markdown("#### Step 1: Upload an image needing hand enhancement")
427
+ main_image_input = gr.ImageEditor(
428
+ height="500px",
429
+ type="pil",
430
+ label="Main Image",
431
+ brush=gr.Brush(
432
+ default_size=30,
433
+ colors=["rgba(117, 48, 254, 0.5)"],
434
+ color_mode="fixed",
435
+ default_color="rgba(117, 48, 254, 0.5)",
436
+ ),
437
+ eraser=gr.Eraser(
438
+ default_size=30,
439
+ ),
440
+ layers=False,
441
+ elem_classes=["image-container", "hide-buttons"]
442
+ )
443
+ main_example = gr.Examples(
444
+ inputs=main_image_input,
445
+ examples_per_page=12,
446
+ examples=clothing_list_path,
447
+ elem_id="example-images",
448
+ outputs=main_image_input,
449
+ )
450
+ with gr.Column():
451
+ with gr.Row():
452
+ with gr.Column():
453
+ gr.Markdown("#### Step 2: Press 'Generate' to get the result")
454
+ output = gr.Image(
455
+ label="Result",
456
+ elem_classes=["image-container", "hide-buttons"],
457
+ interactive=False
458
+ )
459
+ with gr.Row():
460
+ submit_button = gr.Button("Generate")
461
+ submit_button.click(
462
+ fn=generate_image,
463
+ inputs=[main_image_input, current_did],
464
+ outputs=[output, current_did],
465
+ concurrency_limit=None
466
+ )
467
+ with gr.Column():
468
+ main_image_middleware = gr.Image(
469
+ image_mode='RGBA',
470
+ type="pil",
471
+ label="Edited Image",
472
+ elem_classes=["middleware"]
473
+ )
474
+ mask_image_middleware = gr.Image(
475
+ image_mode='RGBA',
476
+ type="pil",
477
+ elem_classes=["middleware"]
478
+ )
479
+ show_case = gr.Examples(
480
+ examples=[
481
+ ["assets/examples/result_01_01.png", "assets/examples/result_01_02.png",
482
+ "assets/examples/result_01_03.png"],
483
+ ["assets/examples/result_02_01.png", "assets/examples/result_02_02.png",
484
+ "assets/examples/result_02_03.png"],
485
+ ["assets/examples/result_03_01.png", "assets/examples/result_03_02.png",
486
+ "assets/examples/result_03_03.png"]
487
+ ],
488
+ inputs=[main_image_middleware, mask_image_middleware, output],
489
+ outputs=[main_image_input, main_image_input, output],
490
+ elem_id="example-res-images",
491
+ fn=process_show_case_image,
492
+ run_on_click=True,
493
+ )
494
+
495
+ WeShop.queue(api_open=False).launch(show_api=False)
assets/clothing/01.png ADDED

Git LFS Details

  • SHA256: 29b4b0789710178cef4e559fcd47226df64a81f12556819bec24228e1b25bb43
  • Pointer size: 131 Bytes
  • Size of remote file: 723 kB
assets/clothing/02.png ADDED

Git LFS Details

  • SHA256: b93abd2fd8fdd7b05afd1b02b36c728bba82849b113827f02053d8e2c9ca2868
  • Pointer size: 131 Bytes
  • Size of remote file: 472 kB
assets/clothing/03.png ADDED

Git LFS Details

  • SHA256: 7beb218d2e2c6d24355b11f0f3da4a9064c6b6d854bb2402f78c47cc4f828a88
  • Pointer size: 131 Bytes
  • Size of remote file: 231 kB
assets/examples/result_01_01.png ADDED

Git LFS Details

  • SHA256: 29b4b0789710178cef4e559fcd47226df64a81f12556819bec24228e1b25bb43
  • Pointer size: 131 Bytes
  • Size of remote file: 723 kB
assets/examples/result_01_02.png ADDED

Git LFS Details

  • SHA256: 2009757dbb790d8247dbf45fd5c9797b72017ebd0ced12c5e34e20fa5591ad19
  • Pointer size: 129 Bytes
  • Size of remote file: 3.57 kB
assets/examples/result_01_03.png ADDED

Git LFS Details

  • SHA256: 6bbc5e958167a5be4db79882622b8d96f495accb350cd506e2d9b0d00b6a5e99
  • Pointer size: 131 Bytes
  • Size of remote file: 636 kB
assets/examples/result_02_01.png ADDED

Git LFS Details

  • SHA256: b93abd2fd8fdd7b05afd1b02b36c728bba82849b113827f02053d8e2c9ca2868
  • Pointer size: 131 Bytes
  • Size of remote file: 472 kB
assets/examples/result_02_02.png ADDED

Git LFS Details

  • SHA256: 21a0e1c8e06e696890cea6d7f9a678ddfa9e72594562eca7d752cc620f66c1ea
  • Pointer size: 129 Bytes
  • Size of remote file: 2.93 kB
assets/examples/result_02_03.png ADDED

Git LFS Details

  • SHA256: 8f80ab2cb1b9b24b4b1f1f562d2e418ef14bc79e6c28b11cde5ad308b4d59250
  • Pointer size: 131 Bytes
  • Size of remote file: 420 kB
assets/examples/result_03_01.png ADDED

Git LFS Details

  • SHA256: 7beb218d2e2c6d24355b11f0f3da4a9064c6b6d854bb2402f78c47cc4f828a88
  • Pointer size: 131 Bytes
  • Size of remote file: 231 kB
assets/examples/result_03_02.png ADDED

Git LFS Details

  • SHA256: f271df48cd6a378f787df570f4776a3219f2befa22101e3bc4285fbda3d7ef97
  • Pointer size: 129 Bytes
  • Size of remote file: 9.5 kB
assets/examples/result_03_03.png ADDED

Git LFS Details

  • SHA256: d0cd1ef287b47ba0e0ead743b2188e8004c7de0fbe5f0afdab0a6474e3879265
  • Pointer size: 132 Bytes
  • Size of remote file: 1.86 MB
assets/title.html ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>WeShopAI Bad Hand Fixer</title>
6
+ <style>
7
+ .title-text {
8
+ display: flex;
9
+ justify-content: center;
10
+ align-items: center;
11
+ text-align: center;
12
+ font-size: 40px;
13
+ }
14
+
15
+ .center-content {
16
+ display: flex;
17
+ justify-content: center;
18
+ align-items: center;
19
+ text-align: center;
20
+ }
21
+
22
+ .content-text {
23
+ text-align: center;
24
+ font-size: 14px;
25
+ padding-right: 10%;
26
+ padding-left: 10%;
27
+ }
28
+
29
+ @media (max-width: 767px) {
30
+ .title-text {
31
+ font-size: 30px;
32
+ }
33
+
34
+ .content-text {
35
+ font-size: 12px;
36
+ padding-right: 2%;
37
+ padding-left: 2%;
38
+ }
39
+
40
+ }
41
+
42
+ @media (max-width: 450px) {
43
+ .title-text {
44
+ font-size: 24px;
45
+ }
46
+
47
+ .content-text {
48
+ font-size: 12px;
49
+ padding-right: 0;
50
+ padding-left: 0;
51
+ }
52
+
53
+ }
54
+
55
+ @media (max-width: 360px) {
56
+ .title-text {
57
+ font-size: 22px;
58
+ }
59
+ }
60
+
61
+ </style>
62
+ </head>
63
+ <body>
64
+ <div>
65
+ <div>
66
+ <div class="title-text">
67
+ <b>WeShopAI Bad Hand Fixer</b>
68
+ </div>
69
+ <br>
70
+ <div class="center-content">
71
+ <a href="https://www.weshop.com/"><img
72
+ src="https://img.shields.io/static/v1?label=Official Website&message=CN&color=red"></a> &ensp;
73
+ <a href="https://www.weshop.ai/"><img
74
+ src="https://img.shields.io/static/v1?label=Official Website&message=EN&color=blue"></a>
75
+ </div>
76
+ <br>
77
+ <div class="content-text">
78
+ Commercial clients are encouraged to evaluate the API capabilities offered at weshop.ai.
79
+ <a href="https://open.weshop.ai/authorization/apikey" style="font-weight: bold;" target="_blank">Get an API
80
+ Key</a> to explore further.
81
+ </div>
82
+ <br>
83
+ <div class="content-text">
84
+ <strong>Disclaimer: </strong>The WeShopAI Bad Hand Fixer Demo on HuggingFace space is free for trials. Any
85
+ solicitation for payment based on the free features we provide on HuggingFace Space is a fraudulent act.
86
+ Beware of scams and do not fall victim to deceit.
87
+ </div>
88
+ </div>
89
+ </div>
90
+ </body>
91
+ </html>
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio==5.27.1
2
+ pydantic==2.10.6
3
+ python-dotenv