File size: 3,185 Bytes
9bf0aab
 
 
 
bd44592
f47ba16
9bf0aab
cdedd76
80910da
 
9bf0aab
 
 
 
 
 
 
 
d2383e6
9bf0aab
 
 
 
 
d2383e6
70dc6b0
 
 
9bf0aab
 
 
 
 
 
 
 
 
 
 
 
80910da
 
cdedd76
 
 
 
 
 
 
 
bd44592
 
9bf0aab
 
 
 
 
 
80910da
9bf0aab
cdedd76
70dc6b0
cdedd76
 
 
 
 
 
 
 
 
 
 
9bf0aab
 
 
 
 
 
08b2f6a
cdedd76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80910da
cdedd76
9bf0aab
 
cdedd76
9bf0aab
 
556c085
9bf0aab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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()