Spaces:
Running
Running
File size: 6,143 Bytes
2066d76 4deeba7 2066d76 4466d3a 4d5a47b 4466d3a 4d5a47b 4466d3a 4d5a47b 4466d3a 4d5a47b 20cc43d 4466d3a 4d5a47b 4466d3a 2066d76 4d5a47b 2066d76 4d5a47b 696e002 2066d76 696e002 2066d76 4d5a47b 696e002 4d5a47b 2066d76 696e002 2066d76 696e002 4d5a47b 696e002 20cc43d 696e002 20cc43d 696e002 2066d76 4c2c03f 696e002 4466d3a 4d5a47b 2066d76 696e002 2066d76 4d5a47b 2066d76 696e002 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 |
import gradio as gr
import requests
prefix = "https://smartfeed-custom-tools.hf.space/gradio_api/file="
extract_model_tag_list = [
"o3",
"o3(poe)",
"gpt-5",
"o4-mini(openrouter)",
"o4-mini-high(openrouter)",
]
extract_model_map = {
"o3": "o3-2025-04-16",
"o3(poe)": "o3(poe)",
"gpt-5": "gpt-5-2025-08-07",
"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,
"extract_model": extract_model,
"extract_prompt": extract_prompt,
"prompt_prefix": prompt_prefix
}
response = requests.post(
"https://api.hkhappymobile.com/tools/change-image-style",
json=data,
headers={"content-type": "application/json"}
)
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):
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, edit_prompt, extract_model, extract_prompt, prompt_prefix
)
if result_image:
success_count += 1
result_image_list.append(result_image)
markdownStr += f"{edit_prompt} <img src='{result_image}' style='zoom: 33%;' />\n"
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, result_image_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")
extract_prompt = gr.Textbox(lines=2, label="Extracted Prompt", value="Accurately extract everything from this photo into a prompt especially the hairstyle excluding the backgrounds. 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)
gallery = gr.Gallery(label="Generated Images")
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, gallery, markdown]
)
demo.launch() |