File size: 6,731 Bytes
2066d76
 
 
4deeba7
2066d76
4466d3a
db5909d
 
4466d3a
db5909d
 
4466d3a
 
4d5a47b
 
4466d3a
db5909d
 
4466d3a
db5909d
 
4466d3a
 
 
 
4d5a47b
 
 
 
20cc43d
4466d3a
4d5a47b
 
 
4466d3a
 
2066d76
 
4d5a47b
d76628b
4d5a47b
 
 
2066d76
 
08cb1fd
 
 
 
 
 
 
 
 
2066d76
 
4d5a47b
 
 
 
 
696e002
2066d76
696e002
 
2066d76
4d5a47b
 
 
696e002
 
4d5a47b
 
 
 
2066d76
 
 
 
 
 
696e002
 
 
 
 
 
 
 
 
2066d76
 
 
696e002
 
4d5a47b
 
696e002
 
 
 
 
 
 
8cf99bb
696e002
 
 
 
8cf99bb
696e002
 
 
 
 
8cf99bb
 
 
 
 
 
 
696e002
 
 
 
 
 
58bc2cd
2066d76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4c2c03f
696e002
 
 
 
 
db5909d
8cf99bb
4d5a47b
 
2066d76
 
 
696e002
 
4d5a47b
2066d76
 
 
 
 
 
696e002
58bc2cd
2066d76
 
 
 
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import gradio as gr
import requests

prefix = "https://smartfeed-custom-tools.hf.space/gradio_api/file="

extract_model_tag_list = [
    "o3(chat)",
    "o3(responses)",
    "o3(poe)",
    "gpt-5(chat)",
    "gpt-5(responses)",
    "o4-mini(openrouter)",
    "o4-mini-high(openrouter)",
]

extract_model_map = {
    "o3(chat)": "o3-2025-04-16",
    "o3(responses)": "o3-2025-04-16(responses)",
    "o3(poe)": "o3(poe)",
    "gpt-5(chat)": "gpt-5-2025-08-07",
    "gpt-5(responses)": "gpt-5-2025-08-07(responses)",
    "o4-mini(openrouter)": "openai/o4-mini",
    "o4-mini-high(openrouter)": "openai/o4-mini-high",
}


def change_image_style(
    image_url,
    style_image_url,
    edit_prompt,
    extract_model_tag,
    extract_prompt,
    prompt_prefix
):
    extract_model = extract_model_map.get(extract_model_tag, "o3")

    data = {
        "image_url": image_url,
        "style_image_url": style_image_url,
        "edit_prompt": edit_prompt,
        "extract_model": extract_model,
        "extract_prompt": extract_prompt,
        "prompt_prefix": prompt_prefix
    }

    try:
        response = requests.post(
            "http://3.20.241.172/tools/change-image-style",
            json=data,
            headers={"content-type": "application/json"}
        )
    except Exception as e:
        error_msg = f"Error occurred while requesting backend tool: {e}"
        return "", "", error_msg

    if response.status_code == 200:
        data = response.json().get("data")
        resultImageUrl = data.get("image_url")
        edit_prompt = data.get("edit_prompt")
        # replace \n to <br>
        edit_prompt = edit_prompt.replace("\n", "<br>")
        return resultImageUrl, edit_prompt, ""
    else:
        error_msg = f"Error: {response.status_code} - {response.text}"
        return "", "", error_msg

def generate_image(
    input_image,
    style_images,
    prompt_count: int,
    image_count: int,
    extract_model,
    extract_prompt,
    prompt_prefix
):

    if not input_image:
        raise gr.Error(f"Please upload an input image! Refer to step 1️⃣")

    if style_images is None:
        raise gr.Error(f"Cannot find any style image! Please refer to step 1️⃣")
    
    style_size = len(style_images)
    if style_size < 1:
        raise gr.Error(f"Please upload at least one style image! Refer to step 1️⃣")
    
    total_count = style_size * prompt_count * image_count
    completed_count = 0
    success_count = 0
    error_count = 0

    inputImageUrl = prefix + input_image

    result_image_list = []
    error_list = []
    markdownStr = ""

    for style_index in range(style_size):
        style_image = style_images[style_index]
        if not style_image:
            error_list.append(f"Style image {style_index + 1} is empty.")
            continue

        for prompt_index in range(prompt_count):
            old_edit_prompt = ""
            for image_index in range(image_count):
                completed_count += 1
                styleImageUrl = prefix + style_image[0]
                result_image, edit_prompt, error_msg = change_image_style(
                    inputImageUrl, styleImageUrl, old_edit_prompt, extract_model, extract_prompt, prompt_prefix
                )

                if result_image:
                    success_count += 1
                    result_image_list.append(result_image)
                    if old_edit_prompt:
                        markdownStr += f"<img src='{result_image}' style='zoom: 33%;' />"
                    else:
                        markdownStr += f"{edit_prompt}<img src='{result_image}' style='zoom: 33%;' />"

                    old_edit_prompt = edit_prompt
                        
                else:
                    error_count += 1
                    error_list.append(f"Error processing style image {style_index + 1}, prompt {prompt_index + 1}, image {image_index + 1}: {error_msg}")

                status = "processing" if completed_count < total_count else "completed"
                status_message = f"Status: {status} ({completed_count}/{total_count}) success: {success_count}, error: {error_count}"
                yield status_message, error_list, markdownStr


def swap_to_gallery(images):
    return gr.update(value=images, visible=True), gr.update(visible=True), gr.update(visible=False)

def remove_back_to_files():
    return gr.update(visible=False), gr.update(visible=False), gr.update(visible=True)

with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column():

            files = gr.File(
                        label="Drag (Select) 1 or more style images",
                        file_types=["image"],
                        file_count="multiple"
                    )
            uploaded_files = gr.Gallery(label="Your images", visible=False, columns=5, rows=1, height=200)
            with gr.Column(visible=False) as clear_button:
                remove_and_reupload = gr.ClearButton(value="Remove and upload new ones", components=files, size="sm")
            input_image = gr.Image(label="Input Image", type="filepath", interactive=True)
            with gr.Row():
                with gr.Column():
                    prompt_count = gr.Number(label="Prompt Count", value=4, precision=0)
                with gr.Column():
                    image_count = gr.Number(label="Image Count", value=3, precision=0)
            extract_model = gr.Dropdown(choices=extract_model_tag_list, label="Extract Model", value="o3(chat)")
            extract_prompt = gr.Textbox(lines=2, label="Extracted Prompt", value="Accurately extract the hairstyle and makeup from this photo into a prompt especially excluding the backgrounds. And Turn to the side, wearing deep blue Off-shoulder Knitted top.  I want to replicate it perfectly. need to be a complete paragraph")
            prompt_prefix = gr.Textbox(lines=1, label="Prompt Prefix", value="change the backgrounds to match this:")

            submit = gr.Button("Submit")

        with gr.Column():
            status_text = gr.Textbox(label="Status", show_label=False, interactive=False)
            error_text = gr.Textbox(label="Error List", show_label=False, interactive=False)
            markdown = gr.Markdown(label="Generated Images")

        files.upload(fn=swap_to_gallery, inputs=files, outputs=[uploaded_files, clear_button, files])
        remove_and_reupload.click(fn=remove_back_to_files, outputs=[uploaded_files, clear_button, files])

        submit.click(
            fn=generate_image,
            inputs=[input_image, uploaded_files, prompt_count, image_count, extract_model, extract_prompt, prompt_prefix],
            outputs=[status_text, error_text, markdown]
        )

    
demo.launch()