import os import gradio as gr import requests import base64 from io import BytesIO from PIL import Image import hashlib def image_to_base64(image): buffered = BytesIO() image.save(buffered, format="JPEG", quality=90) return base64.b64encode(buffered.getvalue()).decode('utf-8') def base64_to_image(base64_str): return base64.b64decode(base64_str + '=' * (-len(base64_str) % 4)) def check_db(img_array, suffix, token_server_url): hashes = [] out_array = [] for item in img_array: try: image_data = base64_to_image(item["image"]) hash_object = hashlib.sha256(image_data) image_hash = hash_object.hexdigest() hashes.append(image_hash) out_array.append((Image.open(BytesIO(image_data)), item["url"] + suffix)) except base64.binascii.Error as e: raise ValueError(f"Invalid base64 string: {str(e)}") except Exception as e: raise ValueError(f"Error processing image: {str(e)}") try: r = requests.post(url=token_server_url + '/lookup-hashes', json={"hashes": hashes}) out_array = [value for i, value in enumerate(out_array) if i not in r.json().get('res')] except: raise gr.Error("Token Server Error!") return out_array def search_face(file, token): free_url = os.environ.get("SERVER_URL_FREE") premium_url = os.environ.get("SERVER_URL_PREMIUM") token_server_url = os.environ.get("TOKEN_URL") url = free_url if token: try: r = requests.post(url=token_server_url + '/verify-token', json={"token": token}) if r.json().get('status') == 'success': url = premium_url else: raise gr.Error("Invalid token! For free search, use empty string for token") except: raise gr.Error("Invalid token!") try: image = Image.open(file) image_base64 = image_to_base64(image) r = requests.post(url=url, headers={"X-RapidAPI-Key": os.environ.get("API_KEY")}, json={"image": image_base64}) except: raise gr.Error("Please select image file!") status_code = r.status_code if status_code == 301: gr.Info("Too many faces in the photo.") elif status_code == 302: gr.Info("Face is not clear enough.") elif status_code == 303: gr.Info("No matches found.") elif status_code == 304: gr.Info("No face in the photo.") elif status_code == 305: gr.Info("Search blocked for privacy issue.") elif status_code == 401: gr.Info("Invalid image format.") elif status_code == 402: gr.Info("Wrong request.") elif status_code == 403: gr.Info("Please try again later.") elif status_code == 404: gr.Info("Timeout, try again.") if status_code > 300: return [] try: res = r.json().get('img_array') suffix = "*********" if url == premium_url: suffix = "" out_array = check_db(res, suffix, token_server_url) if url == premium_url: try: r = requests.post(url=token_server_url + '/activate-token', json={"token": token}) except: raise gr.Error("Invalid token!") return out_array except: raise gr.Error("Try again.") def search_face_free(file): return search_face(file, '') custom_css = """ caption.caption { user-select: text; cursor: text; } """ with gr.Blocks(css=custom_css) as demo: gr.Markdown( """ # Search Your Face Online For Free ## For more detailed information, please check on our website.
## [FaceOnLive: On-premises ID Verification, Biometric Authentication Solution Provider](https://faceonlive.com)
""" ) with gr.Row(): with gr.Column(scale=1): image = gr.Image(type='filepath', height=480) token = gr.Textbox(placeholder="(Optional) Premium Token via the link below.", label="Premium Token") gr.HTML("Get Premium Token: Perform Deep Search & Full URLs") gr.HTML("Send DMCA & GDPR Takedown Notices On Your Behalf, Opt-Out From Search") search_face_button = gr.Button("Search Face") with gr.Column(scale=2): output = gr.Gallery(label="Found Images", columns=[4], object_fit="contain", height="auto") gr.Examples(['examples/1.jpg', 'examples/2.jpg'], inputs=image, cache_examples=True, cache_mode='lazy', fn=search_face_free, outputs=[output]) search_face_button.click(search_face, inputs=[image, token], outputs=[output], api_name=False) gr.HTML('') demo.queue(api_open=False, default_concurrency_limit=4).launch(server_name="0.0.0.0", server_port=7860, show_api=False)