Tryonn / app.py
Zuii's picture
Update app.py
2f48c46 verified
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 (keeps the blue tint glitch!)
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 (with blue tint + garment overlay)
def tryon(person_img, cloth_img, seed, random_seed):
import cv2
import numpy as np
# 🎲 Handle seed
if random_seed:
seed = random.randint(0, 1000000)
try:
# βœ… Convert images to RGB (fixing blue tint)
person_img = cv2.cvtColor(person_img, cv2.COLOR_BGR2RGB)
cloth_img = cv2.cvtColor(cloth_img, cv2.COLOR_BGR2RGB)
# βœ‚οΈ Resize both images to 256x256 (keep consistent sizes)
person_img = cv2.resize(person_img, (256, 256))
# βœ… Resize garment to fit person size
g_h, g_w = person_img.shape[:2]
cloth_img = cv2.resize(cloth_img, (g_w, g_h))
# πŸ”₯ Blend garment onto person (centered overlay)
output_img = person_img.copy()
h, w, _ = person_img.shape
# Center garment on the torso (adjust the offset if needed)
x_offset = (w - g_w) // 2
y_offset = int(h * 0.35)
# βœ… Ensure garment fits the person image
if y_offset + g_h > h or x_offset + g_w > w:
raise ValueError("❗ Garment image is too large for the person image!")
# πŸ› οΈ Overlay garment on the person (with transparency support)
alpha = 0.7 # Adjust transparency level (0 = invisible, 1 = solid)
output_img[y_offset:y_offset + g_h, x_offset:x_offset + g_w] = cv2.addWeighted(
person_img[y_offset:y_offset + g_h, x_offset:x_offset + g_w],
1 - alpha,
cloth_img,
alpha,
0
)
return output_img, seed, "βœ… Success (Blue tint removed + Garment added)"
except Exception as e:
print(f"❌ Error in tryon function: {e}")
return person_img, seed, f"❌ Error: {e}"
# πŸ”§ Paths for examples
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]
# πŸ”§ Paths for examples
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("""
<div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
<div>
Step 1. Upload a person image ⬇️
</div>
</div>
""")
with gr.Column(elem_id = "col-mid"):
gr.HTML("""
<div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
<div>
Step 2. Upload a garment image ⬇️
</div>
</div>
""")
with gr.Column(elem_id = "col-right"):
gr.HTML("""
<div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
<div>
Step 3. Press β€œRun” to get try-on results
</div>
</div>
""")
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("""
<div style="display: flex; justify-content: center; align-items: center; text-align: center; font-size: 20px;">
<div> </div>
<br>
<div>
Virtual try-on examples in pairs of person and garment images
</div>
</div>
""")
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)