Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| import base64 | |
| import os | |
| MODEL = "Qwen/Qwen-Image-Edit-2511" | |
| PROVIDER = "fal-ai" | |
| NUM_IMAGES = 5 | |
| def image_to_data_uri(image_path): | |
| with open(image_path, "rb") as f: | |
| data = base64.b64encode(f.read()).decode("utf-8") | |
| ext = os.path.splitext(image_path)[1].lower() | |
| mime = "image/png" if ext == ".png" else "image/jpeg" | |
| return f"data:{mime};base64,{data}" | |
| def edit_images(img1, img2, img3, img4, img5, prompt, token: gr.OAuthToken | None = None): | |
| if not token: | |
| raise gr.Error("Please sign in with your Hugging Face account first.") | |
| if not prompt or prompt.strip() == "": | |
| raise gr.Error("Please enter a prompt.") | |
| images = [img for img in [img1, img2, img3, img4, img5] if img is not None] | |
| if len(images) == 0: | |
| raise gr.Error("Please upload at least one image.") | |
| client = InferenceClient(provider=PROVIDER, token=token.token) | |
| image_urls = [image_to_data_uri(img) for img in images] | |
| result = client.image_to_image( | |
| model=MODEL, | |
| image=image_urls[0], | |
| prompt=prompt, | |
| extra_body={"image_urls": image_urls} if len(image_urls) > 1 else {}, | |
| ) | |
| return result | |
| def swap(a, b): | |
| return b, a | |
| def send_to(output_img): | |
| return output_img | |
| with gr.Blocks(fill_height=True) as demo: | |
| with gr.Sidebar(): | |
| gr.Markdown("# Qwen Image Edit") | |
| gr.Markdown( | |
| f"Upload one or more images and describe how you want them edited.\n\n" | |
| f"Model: **{MODEL}** via **{PROVIDER}**" | |
| ) | |
| login_btn = gr.LoginButton("Sign in with Hugging Face") | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| with gr.Row(): | |
| img = [ | |
| gr.Image( | |
| label=f"Image {i+1}" if i == 0 else f"Image {i+1} (optional)", | |
| type="filepath", | |
| ) | |
| for i in range(NUM_IMAGES) | |
| ] | |
| with gr.Row(): | |
| swap_btns = [] | |
| for i in range(NUM_IMAGES - 1): | |
| swap_btns.append(gr.Button(f"{i+1} ↔ {i+2}", size="sm")) | |
| prompt = gr.Textbox( | |
| label="Edit Prompt", | |
| placeholder="Describe how you want the image(s) edited...", | |
| lines=3, | |
| ) | |
| submit_btn = gr.Button("Edit", variant="primary") | |
| with gr.Column(scale=2): | |
| output_image = gr.Image(label="Result", type="filepath") | |
| gr.Markdown("**Send result to input:**") | |
| with gr.Row(): | |
| to_btns = [ | |
| gr.Button(f"→ {i+1}", size="sm") for i in range(NUM_IMAGES) | |
| ] | |
| # Swap buttons | |
| for idx, btn in enumerate(swap_btns): | |
| btn.click(fn=swap, inputs=[img[idx], img[idx + 1]], outputs=[img[idx], img[idx + 1]]) | |
| # Send output to input | |
| for idx, btn in enumerate(to_btns): | |
| btn.click(fn=send_to, inputs=[output_image], outputs=[img[idx]]) | |
| # Edit | |
| submit_btn.click( | |
| fn=edit_images, | |
| inputs=[*img, prompt], | |
| outputs=[output_image], | |
| ) | |
| demo.launch() | |