import os import requests import json import time import cv2 import base64 import random import numpy as np import gradio as gr MAX_SEED = 999999 # ✅ Pixelcut API Key pixelcut_api_key = "sk_299d9c6e36d240cbb3dd65fcbac947a4" # ✅ ImgBB API Key (for uploading images to get valid URLs) imgbb_api_key = "03a2ddf1ffa5df33a3999cf20c2fb20f" # 🎯 Convert image to PNG format def convert_to_png(image): return cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 🔥 Resize large images to prevent upload failures (ImgBB limit: 32MB) def resize_image(image, max_size=1024): height, width = image.shape[:2] if max(height, width) > max_size: scale = max_size / max(height, width) return cv2.resize(image, (int(width * scale), int(height * scale))) return image # 🛠️ Upload images to ImgBB (fixed payload!) def upload_image_to_imgbb(image_data): url = f"https://api.imgbb.com/1/upload?key={imgbb_api_key}" files = {"image": image_data} response = requests.post(url, files=files) if response.status_code == 200: return response.json().get("data", {}).get("url") else: print("❌ ImgBB upload failed:", response.text) return None # 🚀 Main try-on function using Pixelcut API def tryon(person_img, garment_img, seed, randomize_seed): start_time = time.time() # 🛑 Check if images are provided if person_img is None or garment_img is None: return None, None, "Empty image" # 🎲 Handle seed randomization if randomize_seed: seed = random.randint(0, MAX_SEED) # 🔥 Convert and resize images to base64 PNG person_img = resize_image(convert_to_png(person_img)) garment_img = resize_image(convert_to_png(garment_img)) _, person_encoded = cv2.imencode('.png', person_img) _, garment_encoded = cv2.imencode('.png', garment_img) # ✅ Upload person and garment images to get valid URLs print("📤 Uploading person image...") person_url = upload_image_to_imgbb(person_encoded) print("📤 Uploading garment image...") garment_url = upload_image_to_imgbb(garment_encoded) if not person_url or not garment_url: return None, None, "Image upload failed — check API keys or connection" # 🌟 Setup Pixelcut API endpoint and headers url = "https://api.developer.pixelcut.ai/v1/remove-background" headers = { 'Content-Type': 'application/json', 'Accept': 'application/json', 'X-API-KEY': pixelcut_api_key } # 🔧 Use the uploaded URLs in the payload person_data = {"image_url": person_url, "format": "png"} garment_data = {"image_url": garment_url, "format": "png"} result_img = None max_retries = 5 retry_delay = 3 # Faster retries now! try: session = requests.Session() # 🛠️ Ensure both images are resized to 256x256 person_img = cv2.resize(person_img, (256, 256)) garment_img = cv2.resize(garment_img, (256, 256)) # 🎯 Handle transparency if the garment has an alpha channel if garment_img.shape[-1] == 4: alpha = garment_img[:, :, 3] / 255.0 for c in range(0, 3): person_img[:, :, c] = (1 - alpha) * person_img[:, :, c] + alpha * garment_img[:, :, c] # 🔧 Optional: Center the garment on the torso area h, w, _ = person_img.shape g_h, g_w, _ = garment_img.shape x_offset = (w - g_w) // 2 y_offset = int(h * 0.35) # Adjust this value for higher/lower garment placement person_img[y_offset:y_offset + g_h, x_offset:x_offset + g_w] = garment_img # ✅ Now the rest of your code continues here (retry loop, API call, etc.) except requests.exceptions.ReadTimeout: print("Timeout!") info = "⚡ Timeout — 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" 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("""