Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -123,29 +123,39 @@ def adjust_size_to_multiple_of_8(width: int, height: int) -> tuple[int, int]:
|
|
| 123 |
new_height = ((height + 7) // 8) * 8
|
| 124 |
return new_width, new_height
|
| 125 |
|
| 126 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
"""배경 이미지 생성 함수"""
|
| 128 |
try:
|
| 129 |
-
#
|
| 130 |
-
|
|
|
|
|
|
|
|
|
|
| 131 |
|
| 132 |
with timer("Background generation"):
|
| 133 |
image = pipe(
|
| 134 |
prompt=prompt,
|
| 135 |
-
width=
|
| 136 |
-
height=
|
| 137 |
num_inference_steps=8,
|
| 138 |
guidance_scale=4.0,
|
| 139 |
).images[0]
|
| 140 |
-
|
| 141 |
-
# 원본 크기로 리사이즈
|
| 142 |
-
if adjusted_width != width or adjusted_height != height:
|
| 143 |
-
image = image.resize((width, height), Image.Resampling.LANCZOS)
|
| 144 |
|
| 145 |
return image
|
| 146 |
except Exception as e:
|
| 147 |
raise gr.Error(f"Background generation failed: {str(e)}")
|
| 148 |
-
|
| 149 |
|
| 150 |
|
| 151 |
def combine_with_background(foreground: Image.Image, background: Image.Image) -> Image.Image:
|
|
@@ -170,7 +180,7 @@ def _gpu_process(img: Image.Image, prompt: str | BoundingBox | None) -> tuple[Im
|
|
| 170 |
time_log.append(f"segment: {time.time() - t0}")
|
| 171 |
return mask, bbox, time_log
|
| 172 |
|
| 173 |
-
def _process(img: Image.Image, prompt: str | BoundingBox | None, bg_prompt: str | None = None) -> tuple[tuple[Image.Image, Image.Image, Image.Image], gr.DownloadButton]:
|
| 174 |
try:
|
| 175 |
if img.width > 2048 or img.height > 2048:
|
| 176 |
orig_res = max(img.width, img.height)
|
|
@@ -183,7 +193,7 @@ def _process(img: Image.Image, prompt: str | BoundingBox | None, bg_prompt: str
|
|
| 183 |
masked_alpha = apply_mask(img, mask, defringe=True)
|
| 184 |
|
| 185 |
if bg_prompt:
|
| 186 |
-
background = generate_background(bg_prompt,
|
| 187 |
combined = combine_with_background(masked_alpha, background)
|
| 188 |
else:
|
| 189 |
combined = Image.alpha_composite(Image.new("RGBA", masked_alpha.size, "white"), masked_alpha)
|
|
@@ -201,8 +211,6 @@ def _process(img: Image.Image, prompt: str | BoundingBox | None, bg_prompt: str
|
|
| 201 |
except Exception as e:
|
| 202 |
raise gr.Error(f"Processing failed: {str(e)}")
|
| 203 |
|
| 204 |
-
|
| 205 |
-
|
| 206 |
def on_change_bbox(prompts: dict[str, Any] | None):
|
| 207 |
return gr.update(interactive=prompts is not None)
|
| 208 |
|
|
@@ -210,13 +218,13 @@ def on_change_bbox(prompts: dict[str, Any] | None):
|
|
| 210 |
def on_change_prompt(img: Image.Image | None, prompt: str | None, bg_prompt: str | None = None):
|
| 211 |
return gr.update(interactive=bool(img and prompt))
|
| 212 |
|
| 213 |
-
def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None) -> tuple[Image.Image, Image.Image]:
|
| 214 |
try:
|
| 215 |
if img is None or prompt.strip() == "":
|
| 216 |
raise gr.Error("Please provide both image and prompt")
|
| 217 |
|
| 218 |
# Process the image
|
| 219 |
-
results, _ = _process(img, prompt, bg_prompt)
|
| 220 |
|
| 221 |
# 합성된 이미지와 추출된 이미지만 반환
|
| 222 |
return results[1], results[2]
|
|
@@ -336,11 +344,21 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
|
|
| 336 |
placeholder="Enter what you want to extract...",
|
| 337 |
interactive=True
|
| 338 |
)
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
process_btn = gr.Button(
|
| 345 |
"Process",
|
| 346 |
variant="primary",
|
|
@@ -378,12 +396,23 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
|
|
| 378 |
queue=False
|
| 379 |
)
|
| 380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
process_btn.click(
|
| 382 |
fn=process_prompt,
|
| 383 |
-
inputs=[input_image, text_prompt, bg_prompt],
|
| 384 |
outputs=[combined_image, extracted_image],
|
| 385 |
queue=True
|
| 386 |
)
|
| 387 |
|
| 388 |
demo.queue(max_size=30, api_open=False)
|
| 389 |
-
demo.launch()
|
|
|
|
| 123 |
new_height = ((height + 7) // 8) * 8
|
| 124 |
return new_width, new_height
|
| 125 |
|
| 126 |
+
def calculate_dimensions(aspect_ratio: str, base_size: int = 512) -> tuple[int, int]:
|
| 127 |
+
"""선택된 비율에 따라 이미지 크기 계산"""
|
| 128 |
+
if aspect_ratio == "1:1":
|
| 129 |
+
return base_size, base_size
|
| 130 |
+
elif aspect_ratio == "16:9":
|
| 131 |
+
return base_size * 16 // 9, base_size
|
| 132 |
+
elif aspect_ratio == "9:16":
|
| 133 |
+
return base_size, base_size * 16 // 9
|
| 134 |
+
elif aspect_ratio == "4:3":
|
| 135 |
+
return base_size * 4 // 3, base_size
|
| 136 |
+
return base_size, base_size
|
| 137 |
+
|
| 138 |
+
def generate_background(prompt: str, aspect_ratio: str) -> Image.Image:
|
| 139 |
"""배경 이미지 생성 함수"""
|
| 140 |
try:
|
| 141 |
+
# 선택된 비율에 따라 크기 계산
|
| 142 |
+
width, height = calculate_dimensions(aspect_ratio)
|
| 143 |
+
|
| 144 |
+
# 8의 배수로 조정
|
| 145 |
+
width, height = adjust_size_to_multiple_of_8(width, height)
|
| 146 |
|
| 147 |
with timer("Background generation"):
|
| 148 |
image = pipe(
|
| 149 |
prompt=prompt,
|
| 150 |
+
width=width,
|
| 151 |
+
height=height,
|
| 152 |
num_inference_steps=8,
|
| 153 |
guidance_scale=4.0,
|
| 154 |
).images[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 155 |
|
| 156 |
return image
|
| 157 |
except Exception as e:
|
| 158 |
raise gr.Error(f"Background generation failed: {str(e)}")
|
|
|
|
| 159 |
|
| 160 |
|
| 161 |
def combine_with_background(foreground: Image.Image, background: Image.Image) -> Image.Image:
|
|
|
|
| 180 |
time_log.append(f"segment: {time.time() - t0}")
|
| 181 |
return mask, bbox, time_log
|
| 182 |
|
| 183 |
+
def _process(img: Image.Image, prompt: str | BoundingBox | None, bg_prompt: str | None = None, aspect_ratio: str = "1:1") -> tuple[tuple[Image.Image, Image.Image, Image.Image], gr.DownloadButton]:
|
| 184 |
try:
|
| 185 |
if img.width > 2048 or img.height > 2048:
|
| 186 |
orig_res = max(img.width, img.height)
|
|
|
|
| 193 |
masked_alpha = apply_mask(img, mask, defringe=True)
|
| 194 |
|
| 195 |
if bg_prompt:
|
| 196 |
+
background = generate_background(bg_prompt, aspect_ratio)
|
| 197 |
combined = combine_with_background(masked_alpha, background)
|
| 198 |
else:
|
| 199 |
combined = Image.alpha_composite(Image.new("RGBA", masked_alpha.size, "white"), masked_alpha)
|
|
|
|
| 211 |
except Exception as e:
|
| 212 |
raise gr.Error(f"Processing failed: {str(e)}")
|
| 213 |
|
|
|
|
|
|
|
| 214 |
def on_change_bbox(prompts: dict[str, Any] | None):
|
| 215 |
return gr.update(interactive=prompts is not None)
|
| 216 |
|
|
|
|
| 218 |
def on_change_prompt(img: Image.Image | None, prompt: str | None, bg_prompt: str | None = None):
|
| 219 |
return gr.update(interactive=bool(img and prompt))
|
| 220 |
|
| 221 |
+
def process_prompt(img: Image.Image, prompt: str, bg_prompt: str | None = None, aspect_ratio: str = "1:1") -> tuple[Image.Image, Image.Image]:
|
| 222 |
try:
|
| 223 |
if img is None or prompt.strip() == "":
|
| 224 |
raise gr.Error("Please provide both image and prompt")
|
| 225 |
|
| 226 |
# Process the image
|
| 227 |
+
results, _ = _process(img, prompt, bg_prompt, aspect_ratio)
|
| 228 |
|
| 229 |
# 합성된 이미지와 추출된 이미지만 반환
|
| 230 |
return results[1], results[2]
|
|
|
|
| 344 |
placeholder="Enter what you want to extract...",
|
| 345 |
interactive=True
|
| 346 |
)
|
| 347 |
+
with gr.Row():
|
| 348 |
+
bg_prompt = gr.Textbox(
|
| 349 |
+
label="Background Prompt (optional)",
|
| 350 |
+
placeholder="Describe the background...",
|
| 351 |
+
interactive=True,
|
| 352 |
+
scale=3
|
| 353 |
+
)
|
| 354 |
+
aspect_ratio = gr.Dropdown(
|
| 355 |
+
choices=["1:1", "16:9", "9:16", "4:3"],
|
| 356 |
+
value="1:1",
|
| 357 |
+
label="Aspect Ratio",
|
| 358 |
+
interactive=True,
|
| 359 |
+
visible=True,
|
| 360 |
+
scale=1
|
| 361 |
+
)
|
| 362 |
process_btn = gr.Button(
|
| 363 |
"Process",
|
| 364 |
variant="primary",
|
|
|
|
| 396 |
queue=False
|
| 397 |
)
|
| 398 |
|
| 399 |
+
# bg_prompt가 비어있을 때 aspect_ratio를 비활성화하는 함수
|
| 400 |
+
def update_aspect_ratio(bg_prompt):
|
| 401 |
+
return gr.update(visible=bool(bg_prompt))
|
| 402 |
+
|
| 403 |
+
bg_prompt.change(
|
| 404 |
+
fn=update_aspect_ratio,
|
| 405 |
+
inputs=bg_prompt,
|
| 406 |
+
outputs=aspect_ratio,
|
| 407 |
+
queue=False
|
| 408 |
+
)
|
| 409 |
+
|
| 410 |
process_btn.click(
|
| 411 |
fn=process_prompt,
|
| 412 |
+
inputs=[input_image, text_prompt, bg_prompt, aspect_ratio],
|
| 413 |
outputs=[combined_image, extracted_image],
|
| 414 |
queue=True
|
| 415 |
)
|
| 416 |
|
| 417 |
demo.queue(max_size=30, api_open=False)
|
| 418 |
+
demo.launch()
|