Chalenger's picture
Update app.py
e9e11cd verified
import os
import sys
import traceback
from io import BytesIO
from PIL import Image
import gradio as gr
from huggingface_hub import InferenceClient
# ============================
# TOKEN / CLIENTE
# ============================
hf_token = os.environ.get("HF_TOKEN")
token_missing = hf_token is None
client = None if token_missing else InferenceClient(
provider="fal-ai",
api_key=hf_token,
)
# ============================
# FUNÇÕES PRINCIPAIS
# ============================
def aspect_ratio_preview(img, max_dim=256):
img_copy = img.copy()
img_copy.thumbnail((max_dim, max_dim))
return img_copy
def generate_images(img1, img2, img3, prompt="", n_outputs=1, aspect_ratio="4:3"):
if token_missing:
return []
images = [img for img in [img1, img2, img3] if img is not None]
if not images:
return [Image.new("RGB", (256, 256), "gray")]
n_outputs = min(int(n_outputs), 3)
outputs = []
user_prompt = f"{prompt.strip()} | {aspect_ratio}" if prompt.strip() else aspect_ratio
for _ in range(n_outputs):
try:
image = client.image_to_image(
images[0],
prompt=user_prompt,
model="Qwen/Qwen-Image-Edit"
)
except Exception:
traceback.print_exc()
image = Image.new("RGB", (256, 256), "gray")
outputs.append(aspect_ratio_preview(image))
return outputs
# ============================
# INTERFACE GRADIO
# ============================
with gr.Blocks(title="Qwen Image Multi-Edit By Chalenger") as demo:
if token_missing:
gr.Markdown("⚠️ **HF_TOKEN not set!** Adicione o token em *Settings → Secrets*.")
gr.Markdown("## Multi-Image Editor for Qwen Image Edit — Max 3 Images")
with gr.Row():
img1 = gr.Image(label="Image Upload 1", type="pil")
img2 = gr.Image(label="Image Upload 2", type="pil")
img3 = gr.Image(label="Image Upload 3", type="pil")
prompt = gr.Textbox(
label="Prompt (opcional)",
placeholder="Description / Descrição",
lines=2
)
nout = gr.Dropdown(
label="Outputs / Saída",
choices=[1, 2, 3],
value=1
)
aspect_ratio_state = gr.State("4:3")
with gr.Row():
btn_4_3 = gr.Button("📺 4:3 CRT")
btn_16_9 = gr.Button("🖥️ 16:9 LED")
btn_9_16 = gr.Button("📱 9:16 Phone")
btn_1_1 = gr.Button("⬛ 1:1 Square")
btn_4_3.click(lambda: "4:3", None, aspect_ratio_state)
btn_16_9.click(lambda: "16:9", None, aspect_ratio_state)
btn_9_16.click(lambda: "9:16", None, aspect_ratio_state)
btn_1_1.click(lambda: "1:1", None, aspect_ratio_state)
with gr.Row():
play_btn = gr.Button("▶️ Start Engine")
stop_btn = gr.Button("⏹️ Kill Tasks")
gallery = gr.Gallery(
label="Outputs / Saídas",
columns=2,
height="500"
)
play_btn.click(
fn=generate_images,
inputs=[img1, img2, img3, prompt, nout, aspect_ratio_state],
outputs=gallery
)
stop_btn.click(lambda: None, None, gallery)
# ============================
# LAUNCH COMPATÍVEL
# ============================
if __name__ == "__main__":
try:
demo.queue() # ativa fila sem depender do launch
demo.launch(
server_name="0.0.0.0",
server_port=7860,
debug=True
)
except Exception:
traceback.print_exc()
sys.exit(1)