Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -15,9 +15,6 @@ import uvicorn
|
|
15 |
import requests
|
16 |
from urllib.parse import quote
|
17 |
from unicodedata import normalize
|
18 |
-
import json
|
19 |
-
import time
|
20 |
-
from html.parser import HTMLParser
|
21 |
|
22 |
root = os.path.dirname(os.path.abspath(__file__))
|
23 |
textures_folder = os.path.join(root, 'textures')
|
@@ -194,8 +191,7 @@ footer:after {
|
|
194 |
}
|
195 |
|
196 |
#textured_result-download-link,
|
197 |
-
#restored_image-download-link
|
198 |
-
#upscaled_image-download-link {
|
199 |
position: absolute;
|
200 |
z-index: 9999;
|
201 |
padding: 2px 4px;
|
@@ -207,21 +203,17 @@ footer:after {
|
|
207 |
transition: 300ms
|
208 |
}
|
209 |
|
210 |
-
#
|
211 |
-
#restored_image-download-link:hover,
|
212 |
-
#upscaled_image-download-link:hover {
|
213 |
color: #99f7a8
|
214 |
}
|
215 |
|
216 |
-
#restored_images.disabled
|
217 |
-
#upscaled_images.disabled {
|
218 |
height: 0px !important;
|
219 |
opacity: 0;
|
220 |
transition: 300ms
|
221 |
}
|
222 |
|
223 |
-
#restored_images.enabled
|
224 |
-
#upscaled_images.enabled {
|
225 |
transition: 300ms
|
226 |
}
|
227 |
""" + preview_css
|
@@ -246,28 +238,24 @@ const PageLoadObserver = new MutationObserver((mutationsList, observer) => {
|
|
246 |
document.querySelector("label[data-testid='05-radio-label']").click()
|
247 |
}, 150);
|
248 |
})
|
249 |
-
|
250 |
-
|
|
|
251 |
const hasChildElements = firstDiv && firstDiv.children.length > 0;
|
252 |
-
const hasImages =
|
253 |
if (hasChildElements || hasImages) {
|
254 |
-
|
255 |
-
|
256 |
} else {
|
257 |
-
|
258 |
-
|
259 |
}
|
260 |
}
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
observer.observe(gallery, { childList: true, subtree: true });
|
267 |
-
checkImagesAndSetClass(gallery);
|
268 |
-
}
|
269 |
-
setupGalleryObserver('restored_images');
|
270 |
-
setupGalleryObserver('upscaled_images');
|
271 |
function magnify(imgID, zoom) {
|
272 |
var img, glass, w, h, bw;
|
273 |
img = document.querySelector(imgID);
|
@@ -355,12 +343,6 @@ const PageLoadObserver = new MutationObserver((mutationsList, observer) => {
|
|
355 |
});
|
356 |
|
357 |
ImageRestoredObserver.observe(document, DownloadLinkObserverOptions);
|
358 |
-
|
359 |
-
const ImageUpscaledObserver = new MutationObserver((mutationsList, observer) => {
|
360 |
-
DownloadLinkObserverCallback(mutationsList, observer, '#upscaled_images img[data-testid="detailed-image"]', '#upscaled_image-download-link', 'upscaled_image-download-link');
|
361 |
-
});
|
362 |
-
|
363 |
-
ImageUpscaledObserver.observe(document, DownloadLinkObserverOptions);
|
364 |
|
365 |
}
|
366 |
}
|
@@ -370,7 +352,6 @@ const PageLoadObserver = new MutationObserver((mutationsList, observer) => {
|
|
370 |
PageLoadObserver.observe(document, { childList: true, subtree: true });
|
371 |
"""
|
372 |
|
373 |
-
|
374 |
def extract_path_from_result(predict_answer):
|
375 |
if isinstance(predict_answer, (tuple, list)):
|
376 |
result = predict_answer[0]
|
@@ -468,7 +449,7 @@ async def restore_upscale(files, restore_method):
|
|
468 |
print(f"restore_upscale: get_file_paths: {file_paths}")
|
469 |
return file_paths
|
470 |
else:
|
471 |
-
return ['
|
472 |
|
473 |
|
474 |
def image_noise_softlight_layer_mix(img, texture, output: str = None, opacity: float = 0.7):
|
@@ -512,169 +493,12 @@ def apply_texture(input_image, textures_choice, opacity_slider):
|
|
512 |
return [result]
|
513 |
|
514 |
|
515 |
-
def get_headers(url: str) -> dict:
|
516 |
-
session = requests.Session()
|
517 |
-
anon_auth = session.get(url)
|
518 |
-
cookies = session.cookies.get_dict()
|
519 |
-
return {
|
520 |
-
'content-type': 'application/json',
|
521 |
-
'cookie': f'csrftoken={cookies["csrftoken"]}; replicate_anonymous_id={cookies["replicate_anonymous_id"]};',
|
522 |
-
'origin': 'https://replicate.com',
|
523 |
-
'x-csrftoken': cookies['csrftoken'],
|
524 |
-
'authority': 'replicate.com',
|
525 |
-
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/jxl,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
526 |
-
'accept-language': 'ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7',
|
527 |
-
'cache-control': 'no-cache',
|
528 |
-
'dnt': '1',
|
529 |
-
'pragma': 'no-cache',
|
530 |
-
'referer': f'{url}?input=http',
|
531 |
-
'sec-ch-ua': '"Chromium";v="117", "Not;A=Brand";v="8"',
|
532 |
-
'sec-ch-ua-mobile': '?0',
|
533 |
-
'sec-ch-ua-platform': '"Windows"',
|
534 |
-
'sec-fetch-dest': 'document',
|
535 |
-
'sec-fetch-mode': 'navigate',
|
536 |
-
'sec-fetch-site': 'same-origin',
|
537 |
-
'sec-fetch-user': '?1',
|
538 |
-
'upgrade-insecure-requests': '1',
|
539 |
-
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36'
|
540 |
-
}
|
541 |
-
|
542 |
-
|
543 |
-
def get_version(url):
|
544 |
-
url = url.rstrip('/') + '/versions'
|
545 |
-
response = requests.get(url)
|
546 |
-
|
547 |
-
class Version(HTMLParser):
|
548 |
-
def __init__(self):
|
549 |
-
super().__init__()
|
550 |
-
self.recording = 0
|
551 |
-
self.data = ''
|
552 |
-
|
553 |
-
def handle_starttag(self, tag, attrs):
|
554 |
-
if tag == 'a':
|
555 |
-
for name, value in attrs:
|
556 |
-
if name == 'href' and '/versions/' in value:
|
557 |
-
self.recording = 1
|
558 |
-
|
559 |
-
def handle_endtag(self, tag):
|
560 |
-
if tag == 'a' and self.recording:
|
561 |
-
self.recording -= 1
|
562 |
-
|
563 |
-
def handle_data(self, data):
|
564 |
-
if self.recording:
|
565 |
-
self.data = data
|
566 |
-
|
567 |
-
parser = Version()
|
568 |
-
parser.feed(response.text)
|
569 |
-
return parser.data.strip()
|
570 |
-
|
571 |
-
|
572 |
-
def replicate_upscale(url: str, image_url: str, upscale: int = 2):
|
573 |
-
version = get_version(url)
|
574 |
-
headers = get_headers(url)
|
575 |
-
session = requests.Session()
|
576 |
-
anon_auth = session.get(url, headers=headers)
|
577 |
-
data = {
|
578 |
-
"version": version,
|
579 |
-
"input": {
|
580 |
-
"img": image_url,
|
581 |
-
"image": image_url,
|
582 |
-
"upscale": upscale,
|
583 |
-
"scale": upscale,
|
584 |
-
"version": "General - RealESRGANplus",
|
585 |
-
},
|
586 |
-
"face_enhance": False,
|
587 |
-
"is_training": False,
|
588 |
-
"stream": False
|
589 |
-
}
|
590 |
-
response = session.post('https://replicate.com/api/predictions', headers=headers, data=json.dumps(data))
|
591 |
-
prediction_id = response.json()['id']
|
592 |
-
while True:
|
593 |
-
response = session.get(f'https://replicate.com/api/predictions/{prediction_id}', headers=headers)
|
594 |
-
print(response.text)
|
595 |
-
status = response.json()['status']
|
596 |
-
if status == 'succeeded':
|
597 |
-
break
|
598 |
-
time.sleep(1)
|
599 |
-
session.close()
|
600 |
-
return response.json()['output']
|
601 |
-
|
602 |
-
|
603 |
-
urls = [
|
604 |
-
'https://replicate.com/cjwbw/real-esrgan',
|
605 |
-
'https://replicate.com/daanelson/real-esrgan-a100',
|
606 |
-
'https://replicate.com/xinntao/realesrgan',
|
607 |
-
]
|
608 |
-
|
609 |
-
|
610 |
-
def upscaler(image):
|
611 |
-
img_url = upload_image(image)
|
612 |
-
|
613 |
-
def run(url):
|
614 |
-
try:
|
615 |
-
return replicate_upscale(url, img_url)
|
616 |
-
except Exception as e:
|
617 |
-
print(e)
|
618 |
-
return 'https://iili.io/JzrxjDP.png'
|
619 |
-
with ThreadPoolExecutor() as executor:
|
620 |
-
futures = {executor.submit(run, url) for url in urls}
|
621 |
-
for future in as_completed(futures):
|
622 |
-
result = future.result()
|
623 |
-
if result is not None:
|
624 |
-
break
|
625 |
-
return [result]
|
626 |
-
|
627 |
-
|
628 |
-
def temp_upload_file(file_path: str) -> str | None:
|
629 |
-
servers = [
|
630 |
-
('https://transfer.sh/', 'fileToUpload'),
|
631 |
-
('https://x0.at/', 'file'),
|
632 |
-
('https://tmpfiles.org/api/v1/upload', 'file'),
|
633 |
-
('https://uguu.se/upload.php', 'files[]')
|
634 |
-
]
|
635 |
-
for i in range(3):
|
636 |
-
for server, file_key in servers:
|
637 |
-
try:
|
638 |
-
with open(file_path, 'rb') as f:
|
639 |
-
files = {file_key: f}
|
640 |
-
response = requests.post(server, files=files)
|
641 |
-
if response.status_code == 200:
|
642 |
-
if server == 'https://transfer.sh/':
|
643 |
-
return response.text.replace("https://transfer.sh/","https://transfer.sh/get/").replace("\n","")
|
644 |
-
elif server == 'https://tmpfiles.org/api/v1/upload':
|
645 |
-
response_json = response.json()
|
646 |
-
if response_json['status'] == 'success':
|
647 |
-
return response_json['data']['url'].replace("https://tmpfiles.org/", "https://tmpfiles.org/dl/")
|
648 |
-
elif server == 'https://uguu.se/upload.php':
|
649 |
-
response_json = response.json()
|
650 |
-
if response_json['success']:
|
651 |
-
return response_json['files'][0]['url']
|
652 |
-
else:
|
653 |
-
return response.text
|
654 |
-
except Exception as e:
|
655 |
-
print(f'{server}: {e}')
|
656 |
-
return None
|
657 |
-
|
658 |
-
|
659 |
-
def upload_image(image_path: str) -> str | None:
|
660 |
-
files = {'source': open(image_path, "rb")}
|
661 |
-
data = {'key': '6d207e02198a847aa98d0a2a901485a5', 'action': 'upload', 'format': 'json'}
|
662 |
-
response = requests.post('https://freeimage.host/api/1/upload', files=files, data=data)
|
663 |
-
if response.json()["status_code"] == 200:
|
664 |
-
return response.json()["image"]["url"]
|
665 |
-
else:
|
666 |
-
return temp_upload_file(image_path)
|
667 |
-
|
668 |
with gr.Blocks(analytics_enabled=False, css=radio_css) as demo:
|
669 |
-
with gr.Tab(label="апскейл", elem_id="upscale_tab"):
|
670 |
-
file_output = gr.Gallery(label="", container=True, object_fit="cover", columns=4, rows=4, allow_preview=True, preview=True, show_share_button=False, show_download_button=False, elem_id="upscaled_images")
|
671 |
-
upload_button = gr.UploadButton("выбор одного изображения для обработки", file_types=["image"], file_count="single", variant="primary")
|
672 |
-
upload_button.upload(fn=upscaler, inputs=[upload_button], outputs=file_output, api_name="upscale")
|
673 |
with gr.Tab(label="восстановление лиц", id=1, elem_id="restore_tab"):
|
674 |
restore_method = gr.Radio(["codeformer", "gfpgan", "оба"], value="codeformer", label="", interactive=True)
|
675 |
restore_method.change(fn=lambda x: print(f"restore_method value = {x}"), inputs=restore_method, api_name="show_selected_method")
|
676 |
file_output = gr.Gallery(label="", container=True, object_fit="cover", columns=4, rows=4, allow_preview=True, preview=True, show_share_button=False, show_download_button=False, elem_id="restored_images")
|
677 |
-
upload_button = gr.UploadButton("выбор
|
678 |
upload_button.upload(fn=restore_upscale, inputs=[upload_button, restore_method], outputs=file_output, api_name="face_restore")
|
679 |
with gr.Tab(label="наложение зернистости пленки и шума", id=2, elem_id="textures_tab"):
|
680 |
with gr.Row(variant="compact", elem_id="textures_tab_images"):
|
@@ -687,7 +511,6 @@ with gr.Blocks(analytics_enabled=False, css=radio_css) as demo:
|
|
687 |
apply_button.click(fn=apply_texture, inputs=[input_image, textures_choice, opacity_slider], outputs=result_image, api_name="texturize")
|
688 |
|
689 |
|
690 |
-
|
691 |
app = FastAPI()
|
692 |
|
693 |
|
|
|
15 |
import requests
|
16 |
from urllib.parse import quote
|
17 |
from unicodedata import normalize
|
|
|
|
|
|
|
18 |
|
19 |
root = os.path.dirname(os.path.abspath(__file__))
|
20 |
textures_folder = os.path.join(root, 'textures')
|
|
|
191 |
}
|
192 |
|
193 |
#textured_result-download-link,
|
194 |
+
#restored_image-download-link {
|
|
|
195 |
position: absolute;
|
196 |
z-index: 9999;
|
197 |
padding: 2px 4px;
|
|
|
203 |
transition: 300ms
|
204 |
}
|
205 |
|
206 |
+
#download-link:hover {
|
|
|
|
|
207 |
color: #99f7a8
|
208 |
}
|
209 |
|
210 |
+
#restored_images.disabled {
|
|
|
211 |
height: 0px !important;
|
212 |
opacity: 0;
|
213 |
transition: 300ms
|
214 |
}
|
215 |
|
216 |
+
#restored_images.enabled {
|
|
|
217 |
transition: 300ms
|
218 |
}
|
219 |
""" + preview_css
|
|
|
238 |
document.querySelector("label[data-testid='05-radio-label']").click()
|
239 |
}, 150);
|
240 |
})
|
241 |
+
let RestoredGallery = document.getElementById('restored_images');
|
242 |
+
function checkImagesAndSetClass() {
|
243 |
+
const firstDiv = RestoredGallery.querySelector('div:first-child');
|
244 |
const hasChildElements = firstDiv && firstDiv.children.length > 0;
|
245 |
+
const hasImages = RestoredGallery.querySelectorAll('img').length > 0;
|
246 |
if (hasChildElements || hasImages) {
|
247 |
+
RestoredGallery.classList.add('enabled');
|
248 |
+
RestoredGallery.classList.remove('disabled');
|
249 |
} else {
|
250 |
+
RestoredGallery.classList.add('disabled');
|
251 |
+
RestoredGallery.classList.remove('enabled');
|
252 |
}
|
253 |
}
|
254 |
+
const FaceResoreResultCheck = new MutationObserver((mutations) => {
|
255 |
+
checkImagesAndSetClass();
|
256 |
+
});
|
257 |
+
FaceResoreResultCheck.observe(RestoredGallery, {childList: true, subtree: true});
|
258 |
+
checkImagesAndSetClass();
|
|
|
|
|
|
|
|
|
|
|
259 |
function magnify(imgID, zoom) {
|
260 |
var img, glass, w, h, bw;
|
261 |
img = document.querySelector(imgID);
|
|
|
343 |
});
|
344 |
|
345 |
ImageRestoredObserver.observe(document, DownloadLinkObserverOptions);
|
|
|
|
|
|
|
|
|
|
|
|
|
346 |
|
347 |
}
|
348 |
}
|
|
|
352 |
PageLoadObserver.observe(document, { childList: true, subtree: true });
|
353 |
"""
|
354 |
|
|
|
355 |
def extract_path_from_result(predict_answer):
|
356 |
if isinstance(predict_answer, (tuple, list)):
|
357 |
result = predict_answer[0]
|
|
|
449 |
print(f"restore_upscale: get_file_paths: {file_paths}")
|
450 |
return file_paths
|
451 |
else:
|
452 |
+
return [os.path.join(root, 'error.png')]
|
453 |
|
454 |
|
455 |
def image_noise_softlight_layer_mix(img, texture, output: str = None, opacity: float = 0.7):
|
|
|
493 |
return [result]
|
494 |
|
495 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
496 |
with gr.Blocks(analytics_enabled=False, css=radio_css) as demo:
|
|
|
|
|
|
|
|
|
497 |
with gr.Tab(label="восстановление лиц", id=1, elem_id="restore_tab"):
|
498 |
restore_method = gr.Radio(["codeformer", "gfpgan", "оба"], value="codeformer", label="", interactive=True)
|
499 |
restore_method.change(fn=lambda x: print(f"restore_method value = {x}"), inputs=restore_method, api_name="show_selected_method")
|
500 |
file_output = gr.Gallery(label="", container=True, object_fit="cover", columns=4, rows=4, allow_preview=True, preview=True, show_share_button=False, show_download_button=False, elem_id="restored_images")
|
501 |
+
upload_button = gr.UploadButton("выбор изображений для обработки", file_types=["image"], file_count="multiple", variant="primary")
|
502 |
upload_button.upload(fn=restore_upscale, inputs=[upload_button, restore_method], outputs=file_output, api_name="face_restore")
|
503 |
with gr.Tab(label="наложение зернистости пленки и шума", id=2, elem_id="textures_tab"):
|
504 |
with gr.Row(variant="compact", elem_id="textures_tab_images"):
|
|
|
511 |
apply_button.click(fn=apply_texture, inputs=[input_image, textures_choice, opacity_slider], outputs=result_image, api_name="texturize")
|
512 |
|
513 |
|
|
|
514 |
app = FastAPI()
|
515 |
|
516 |
|