Nightfury16 commited on
Commit
cae10fc
·
1 Parent(s): f6475e3
Files changed (1) hide show
  1. app.py +61 -57
app.py CHANGED
@@ -2,121 +2,125 @@ import gradio as gr
2
  import requests
3
  import fal_client
4
  import os
5
- import json
6
- import time
7
  import base64
8
- import io
9
  from PIL import Image
 
10
 
11
  RUNPOD_API_KEY = os.getenv("RUNPOD_API_KEY")
12
  FAL_KEY = os.getenv("FAL_KEY")
13
-
14
- QWEN_ENDPOINT_ID = os.environ["ENDPOINTID"]
15
 
16
  os.environ["FAL_KEY"] = FAL_KEY if FAL_KEY else ""
17
 
18
  DEFAULT_PROMPT = "Add furnishings and accessories to this room as an interior designer would do for a real estate staging. The generated image shall have the exact same dimensions as the original image and architectural details. Respect doorways and windows and make sure they are consistent with the source image and not blocked by furniture. Use cute accessories and with appropriate wall space, add smart simple graphic paintings. Use neutral colors with light colored accents to match the colors of the room. Give the area an attractive glow."
19
 
20
- def get_as_base64(url):
21
- """Helper to convert image URL to base64 for the Qwen endpoint"""
22
- response = requests.get(url)
23
- return base64.b64encode(response.content).decode('utf-8')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
- def run_banana(image_url, prompt):
26
  url = "https://api.runpod.ai/v2/nano-banana-edit/runsync"
27
  headers = {"Content-Type": "application/json", "Authorization": f"Bearer {RUNPOD_API_KEY}"}
28
  payload = {
29
  "input": {
30
  "prompt": prompt,
31
- "images": [image_url],
32
  "enable_safety_checker": True
33
  }
34
  }
35
  try:
36
  response = requests.post(url, headers=headers, json=payload, timeout=90)
37
  return response.json()["output"][0]
38
- except Exception as e:
39
  return None
40
 
41
- def run_qwen(image_url, prompt):
42
- """Updated to use endpoint jzpm1xin5cprff with base64 logic"""
43
  url = f"https://api.runpod.ai/v2/{QWEN_ENDPOINT_ID}/runsync"
44
  headers = {"Content-Type": "application/json", "Authorization": f"Bearer {RUNPOD_API_KEY}"}
45
-
46
- try:
47
- img_b64 = get_as_base64(image_url)
48
- payload = {
49
- "input": {
50
- "image": img_b64,
51
- "prompt": prompt,
52
- "seed": 42,
53
- "use_lightning": True,
54
- "true_guidance_scale": 2.5,
55
- "num_inference_steps": 4
56
- }
57
  }
 
 
58
  response = requests.post(url, headers=headers, json=payload, timeout=90)
59
- res_data = response.json()
60
-
61
- img_data = res_data["output"]["images"][0]
62
  return f"data:image/png;base64,{img_data}"
63
- except Exception as e:
64
- print(f"Qwen Error: {e}")
65
  return None
66
 
67
- def run_fal_flux(image_url, prompt):
68
  try:
69
  handler = fal_client.submit(
70
  "fal-ai/flux-2/edit",
71
- arguments={
72
- "prompt": prompt,
73
- "image_urls": [image_url]
74
- }
75
  )
76
  result = handler.get()
77
  return result['images'][0]['url']
78
- except Exception as e:
79
  return None
80
 
81
- def compare_models(image_url, prompt):
82
- if not image_url:
 
 
83
  return None, None, None
84
- res_banana = run_banana(image_url, prompt)
85
- res_qwen = run_qwen(image_url, prompt)
86
- res_fal = run_fal_flux(image_url, prompt)
87
- return res_banana, res_qwen, res_fal
88
 
89
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
 
 
 
 
 
 
 
90
  gr.Markdown("# 🛋️ Interior Design Model Arena")
91
- gr.Markdown("Compare specialized staging models side-by-side.")
92
 
93
  with gr.Row():
94
  with gr.Column(scale=1):
95
- input_url = gr.Textbox(label="Source Image URL", placeholder="Paste a link to your room image...")
96
- input_prompt = gr.Textbox(label="Edit Prompt", value=DEFAULT_PROMPT, lines=5)
 
97
  run_btn = gr.Button("Generate Comparison", variant="primary")
98
 
99
  with gr.Row():
100
  with gr.Column():
101
- gr.Markdown("### Qwen-Edit (New)")
102
- gr.Markdown("**Price: $0.004 - $0.008 /req**")
103
  out_qwen = gr.Image(label="Qwen Result", interactive=False)
104
 
105
  with gr.Column():
106
- gr.Markdown("### Flux-2 Edit")
107
- gr.Markdown("**Price: $0.024 /req**")
108
  out_fal = gr.Image(label="Flux Result", interactive=False)
109
 
110
  with gr.Column():
111
- gr.Markdown("### Nano-Banana")
112
- gr.Markdown("**Price: $0.039 /req**")
113
  out_banana = gr.Image(label="Banana Result", interactive=False)
114
 
115
  run_btn.click(
116
  fn=compare_models,
117
- inputs=[input_url, input_prompt],
118
- outputs=[out_banana, out_qwen, out_fal]
119
  )
120
 
121
- if __name__ == "__main__":
122
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
2
  import requests
3
  import fal_client
4
  import os
 
 
5
  import base64
 
6
  from PIL import Image
7
+ import io
8
 
9
  RUNPOD_API_KEY = os.getenv("RUNPOD_API_KEY")
10
  FAL_KEY = os.getenv("FAL_KEY")
11
+ QWEN_ENDPOINT_ID = "jzpm1xin5cprff"
 
12
 
13
  os.environ["FAL_KEY"] = FAL_KEY if FAL_KEY else ""
14
 
15
  DEFAULT_PROMPT = "Add furnishings and accessories to this room as an interior designer would do for a real estate staging. The generated image shall have the exact same dimensions as the original image and architectural details. Respect doorways and windows and make sure they are consistent with the source image and not blocked by furniture. Use cute accessories and with appropriate wall space, add smart simple graphic paintings. Use neutral colors with light colored accents to match the colors of the room. Give the area an attractive glow."
16
 
17
+ def process_image_source(image_file, image_url):
18
+ """
19
+ Determines if we should use the uploaded file or the URL.
20
+ Returns base64 for Qwen and a URL (or data URI) for others.
21
+ """
22
+ if image_file is not None:
23
+ with open(image_file, "rb") as f:
24
+ file_bytes = f.read()
25
+ b64_str = base64.b64encode(file_bytes).decode('utf-8')
26
+ fal_url = fal_client.upload_file(image_file)
27
+ return b64_str, fal_url, f"data:image/png;base64,{b64_str}"
28
+
29
+ elif image_url and image_url.strip():
30
+ response = requests.get(image_url)
31
+ if response.status_code == 200:
32
+ b64_str = base64.b64encode(response.content).decode('utf-8')
33
+ return b64_str, image_url, image_url
34
+
35
+ return None, None, None
36
 
37
+ def run_banana(image_source_url, prompt):
38
  url = "https://api.runpod.ai/v2/nano-banana-edit/runsync"
39
  headers = {"Content-Type": "application/json", "Authorization": f"Bearer {RUNPOD_API_KEY}"}
40
  payload = {
41
  "input": {
42
  "prompt": prompt,
43
+ "images": [image_source_url],
44
  "enable_safety_checker": True
45
  }
46
  }
47
  try:
48
  response = requests.post(url, headers=headers, json=payload, timeout=90)
49
  return response.json()["output"][0]
50
+ except:
51
  return None
52
 
53
+ def run_qwen(b64_img, prompt):
 
54
  url = f"https://api.runpod.ai/v2/{QWEN_ENDPOINT_ID}/runsync"
55
  headers = {"Content-Type": "application/json", "Authorization": f"Bearer {RUNPOD_API_KEY}"}
56
+ payload = {
57
+ "input": {
58
+ "image": b64_img,
59
+ "prompt": prompt,
60
+ "seed": 42,
61
+ "use_lightning": True,
62
+ "true_guidance_scale": 2.5,
63
+ "num_inference_steps": 4
 
 
 
 
64
  }
65
+ }
66
+ try:
67
  response = requests.post(url, headers=headers, json=payload, timeout=90)
68
+ img_data = response.json()["output"]["images"][0]
 
 
69
  return f"data:image/png;base64,{img_data}"
70
+ except:
 
71
  return None
72
 
73
+ def run_fal_flux(fal_hosted_url, prompt):
74
  try:
75
  handler = fal_client.submit(
76
  "fal-ai/flux-2/edit",
77
+ arguments={"prompt": prompt, "image_urls": [fal_hosted_url]}
 
 
 
78
  )
79
  result = handler.get()
80
  return result['images'][0]['url']
81
+ except:
82
  return None
83
 
84
+ def compare_models(image_file, image_url, prompt):
85
+ b64_img, fal_url, general_url = process_image_source(image_file, image_url)
86
+
87
+ if not b64_img:
88
  return None, None, None
 
 
 
 
89
 
90
+ res_qwen = run_qwen(b64_img, prompt)
91
+ res_fal = run_fal_flux(fal_url, prompt)
92
+ res_banana = run_banana(general_url, prompt)
93
+
94
+ return res_qwen, res_fal, res_banana
95
+
96
+ # UI
97
+ with gr.Blocks() as demo:
98
  gr.Markdown("# 🛋️ Interior Design Model Arena")
 
99
 
100
  with gr.Row():
101
  with gr.Column(scale=1):
102
+ input_file = gr.Image(label="Upload Room Image", type="filepath")
103
+ input_url = gr.Textbox(label="OR: Source Image URL", placeholder="https://...")
104
+ input_prompt = gr.Textbox(label="Edit Prompt", value=DEFAULT_PROMPT, lines=4)
105
  run_btn = gr.Button("Generate Comparison", variant="primary")
106
 
107
  with gr.Row():
108
  with gr.Column():
109
+ gr.Markdown("### Qwen-Edit\n**Price: $0.004 - $0.008**")
 
110
  out_qwen = gr.Image(label="Qwen Result", interactive=False)
111
 
112
  with gr.Column():
113
+ gr.Markdown("### Flux-2 Edit\n**Price: $0.024**")
 
114
  out_fal = gr.Image(label="Flux Result", interactive=False)
115
 
116
  with gr.Column():
117
+ gr.Markdown("### Nano-Banana\n**Price: $0.039**")
 
118
  out_banana = gr.Image(label="Banana Result", interactive=False)
119
 
120
  run_btn.click(
121
  fn=compare_models,
122
+ inputs=[input_file, input_url, input_prompt],
123
+ outputs=[out_qwen, out_fal, out_banana]
124
  )
125
 
126
+ demo.launch(server_name="0.0.0.0", server_port=7860)