Tryonn / app.py
Zuii's picture
Update app.py
2f48c46 verified
raw
history blame
8.03 kB
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)