import os import requests import json import base64 import cv2 import numpy as np import time import random MAX_SEED = 1000000 def tryon(person_img, garment_img, seed, randomize_seed): start_time = time.time() if person_img is None or garment_img is None: return None, None, "Empty image" if randomize_seed: seed = random.randint(0, MAX_SEED) # Encode images encoded_person_img = cv2.imencode('.jpg', cv2.cvtColor(person_img, cv2.COLOR_RGB2BGR))[1].tobytes() encoded_person_img = base64.b64encode(encoded_person_img).decode('utf-8') encoded_garment_img = cv2.imencode('.jpg', cv2.cvtColor(garment_img, cv2.COLOR_RGB2BGR))[1].tobytes() encoded_garment_img = base64.b64encode(encoded_garment_img).decode('utf-8') # Pixelcut API setup url = "https://api.developer.pixelcut.ai/v1/remove-background" pixelcut_api_key = os.environ.get('PIXELCUT_API_KEY') headers = { 'Content-Type': 'application/json', 'X-API-KEY': pixelcut_api_key } data = { "clothImage": encoded_garment_img, "humanImage": encoded_person_img, "seed": seed } result_img = None max_retries = 5 retry_delay = 5 try: session = requests.Session() # Retry loop for "Too many users" error for attempt in range(max_retries): response = session.post(url, headers=headers, data=json.dumps(data), timeout=60) print("Response code:", response.status_code) if response.status_code == 200: result = response.json().get('result', {}) status = result.get('status', '') if status == "success": result_data = base64.b64decode(result['result']) result_np = np.frombuffer(result_data, np.uint8) result_img = cv2.imdecode(result_np, cv2.IMREAD_UNCHANGED) result_img = cv2.cvtColor(result_img, cv2.COLOR_RGB2BGR) info = "Success" break else: info = "Try again later" else: print("Full response:", response.text) if "Too many users" in response.text: print(f"Attempt {attempt + 1}/{max_retries}: API busy. Retrying in {retry_delay} seconds...") time.sleep(retry_delay) else: info = f"Error: {response.status_code} - {response.text}" break else: info = "API still overloaded — please try again later." except requests.exceptions.ReadTimeout: print("Timeout") info = "Too many users, please try again later" raise gr.Error("Too many users, please try again later") except Exception as err: print(f"Other error: {err}") info = "Error, please contact the admin" end_time = time.time() print(f"Time used: {end_time - start_time}") return result_img, seed, info example_path = os.path.join(os.path.dirname(__file__), 'assets') garm_list = os.listdir(os.path.join(example_path,"cloth")) garm_list_path = [os.path.join(example_path,"cloth",garm) for garm in garm_list] human_list = os.listdir(os.path.join(example_path,"human")) human_list_path = [os.path.join(example_path,"human",human) for human in human_list] css=""" #col-left { margin: 0 auto; max-width: 430px; } #col-mid { margin: 0 auto; max-width: 430px; } #col-right { margin: 0 auto; max-width: 430px; } #col-showcase { margin: 0 auto; max-width: 1100px; } #button { color: blue; } """ def load_description(fp): with open(fp, 'r', encoding='utf-8') as f: content = f.read() return content def change_imgs(image1, image2): return image1, image2 with gr.Blocks(css=css) as Tryon: gr.HTML(load_description("assets/new_title.md")) with gr.Row(): with gr.Column(elem_id = "col-left"): gr.HTML("""
Step 1. Upload a person image ⬇️
""") with gr.Column(elem_id = "col-mid"): gr.HTML("""
Step 2. Upload a garment image ⬇️
""") with gr.Column(elem_id = "col-right"): gr.HTML("""
Step 3. Press “Run” to get try-on results
""") with gr.Row(): with gr.Column(elem_id = "col-left"): imgs = gr.Image(label="Person image", sources='upload', type="numpy") # category = gr.Dropdown(label="Garment category", choices=['upper_body', 'lower_body', 'dresses'], value="upper_body") example = gr.Examples( inputs=imgs, examples_per_page=12, examples=human_list_path ) with gr.Column(elem_id = "col-mid"): garm_img = gr.Image(label="Garment image", sources='upload', type="numpy") example = gr.Examples( inputs=garm_img, examples_per_page=12, examples=garm_list_path ) with gr.Column(elem_id = "col-right"): image_out = gr.Image(label="Result", show_share_button=False) with gr.Row(): seed = gr.Slider( label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, ) randomize_seed = gr.Checkbox(label="Random seed", value=True) with gr.Row(): seed_used = gr.Number(label="Seed used") result_info = gr.Text(label="Response") # try_button = gr.Button(value="Run", elem_id="button") test_button = gr.Button(value="Run", elem_id="button") # try_button.click(fn=start_tryon, inputs=[imgs, garm_img, seed, randomize_seed], outputs=[image_out, seed_used, result_info], api_name='tryon',concurrency_limit=10) test_button.click(fn=tryon, inputs=[imgs, garm_img, seed, randomize_seed], outputs=[image_out, seed_used, result_info], api_name=False, concurrency_limit=45) with gr.Column(elem_id = "col-showcase"): gr.HTML("""

Virtual try-on examples in pairs of person and garment images
""") show_case = gr.Examples( examples=[ ["assets/examples/model2.png", "assets/examples/garment2.png", "assets/examples/result2.png"], ["assets/examples/model3.png", "assets/examples/garment3.png", "assets/examples/result3.png"], ["assets/examples/model1.png", "assets/examples/garment1.png", "assets/examples/result1.png"], ], inputs=[imgs, garm_img, image_out], label=None ) Tryon.queue(api_open=False).launch(show_api=False)