Spaces:
Running
on
Zero
Running
on
Zero
test
#37
by
akmam
- opened
- README.md +1 -1
- app.py +9 -69
- requirements.txt +2 -4
README.md
CHANGED
@@ -4,7 +4,7 @@ emoji: 🔅
|
|
4 |
colorFrom: gray
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: apache-2.0
|
|
|
4 |
colorFrom: gray
|
5 |
colorTo: purple
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 4.42.0
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: apache-2.0
|
app.py
CHANGED
@@ -169,55 +169,9 @@ def preview_image_and_mask(image, width, height, overlap_percentage, resize_opti
|
|
169 |
return preview
|
170 |
|
171 |
@spaces.GPU(duration=24)
|
172 |
-
def infer(
|
173 |
-
image,
|
174 |
-
width,
|
175 |
-
height,
|
176 |
-
overlap_percentage,
|
177 |
-
num_inference_steps,
|
178 |
-
resize_option,
|
179 |
-
custom_resize_percentage,
|
180 |
-
prompt_input,
|
181 |
-
alignment,
|
182 |
-
overlap_left,
|
183 |
-
overlap_right,
|
184 |
-
overlap_top,
|
185 |
-
overlap_bottom
|
186 |
-
):
|
187 |
-
"""
|
188 |
-
Generate an outpainted image using Stable Diffusion XL with ControlNet guidance.
|
189 |
|
190 |
-
This function performs intelligent image outpainting by expanding the input image
|
191 |
-
according to the specified target dimensions and alignment, generating new content
|
192 |
-
guided by a textual prompt. It uses a ControlNet-enabled diffusion pipeline to ensure
|
193 |
-
coherent image extension.
|
194 |
-
|
195 |
-
Args:
|
196 |
-
image (PIL.Image): The input image to be outpainted.
|
197 |
-
width (int): The target width of the output image.
|
198 |
-
height (int): The target height of the output image.
|
199 |
-
overlap_percentage (int): Percentage of overlap between original and outpainted regions for seamless blending.
|
200 |
-
num_inference_steps (int): Number of inference steps for image generation. Higher values yield better results.
|
201 |
-
resize_option (str): Predefined or custom percentage to resize the input image ("Full", "50%", "33%", "25%", or "Custom").
|
202 |
-
custom_resize_percentage (int): Custom resize percentage if resize_option is "Custom".
|
203 |
-
prompt_input (str): A text prompt describing desired content for the generated region.
|
204 |
-
alignment (str): Alignment of the original image within the canvas ("Middle", "Left", "Right", "Top", "Bottom").
|
205 |
-
overlap_left (bool): Whether to allow blending on the left edge.
|
206 |
-
overlap_right (bool): Whether to allow blending on the right edge.
|
207 |
-
overlap_top (bool): Whether to allow blending on the top edge.
|
208 |
-
overlap_bottom (bool): Whether to allow blending on the bottom edge.
|
209 |
-
|
210 |
-
Yields:
|
211 |
-
Tuple[PIL.Image, PIL.Image]:
|
212 |
-
- The intermediate ControlNet input image (showing the masked area).
|
213 |
-
- The final generated image with the inpainted region.
|
214 |
-
"""
|
215 |
-
background, mask = prepare_image_and_mask(
|
216 |
-
image, width, height, overlap_percentage,
|
217 |
-
resize_option, custom_resize_percentage, alignment,
|
218 |
-
overlap_left, overlap_right, overlap_top, overlap_bottom
|
219 |
-
)
|
220 |
-
|
221 |
if not can_expand(background.width, background.height, width, height, alignment):
|
222 |
alignment = "Middle"
|
223 |
|
@@ -248,7 +202,6 @@ def infer(
|
|
248 |
|
249 |
yield background, cnet_image
|
250 |
|
251 |
-
|
252 |
def clear_result():
|
253 |
"""Clears the result ImageSlider."""
|
254 |
return gr.update(value=None)
|
@@ -421,47 +374,41 @@ with gr.Blocks(css=css) as demo:
|
|
421 |
use_as_input_button.click(
|
422 |
fn=use_output_as_input,
|
423 |
inputs=[result],
|
424 |
-
outputs=[input_image]
|
425 |
-
show_api=False
|
426 |
)
|
427 |
|
428 |
target_ratio.change(
|
429 |
fn=preload_presets,
|
430 |
inputs=[target_ratio, width_slider, height_slider],
|
431 |
outputs=[width_slider, height_slider, settings_panel],
|
432 |
-
queue=False
|
433 |
-
show_api=False
|
434 |
)
|
435 |
|
436 |
width_slider.change(
|
437 |
fn=select_the_right_preset,
|
438 |
inputs=[width_slider, height_slider],
|
439 |
outputs=[target_ratio],
|
440 |
-
queue=False
|
441 |
-
show_api=False
|
442 |
)
|
443 |
|
444 |
height_slider.change(
|
445 |
fn=select_the_right_preset,
|
446 |
inputs=[width_slider, height_slider],
|
447 |
outputs=[target_ratio],
|
448 |
-
queue=False
|
449 |
-
show_api=False
|
450 |
)
|
451 |
|
452 |
resize_option.change(
|
453 |
fn=toggle_custom_resize_slider,
|
454 |
inputs=[resize_option],
|
455 |
outputs=[custom_resize_percentage],
|
456 |
-
queue=False
|
457 |
-
show_api=False
|
458 |
)
|
459 |
|
460 |
run_button.click( # Clear the result
|
461 |
fn=clear_result,
|
462 |
inputs=None,
|
463 |
outputs=result,
|
464 |
-
show_api=False
|
465 |
).then( # Generate the new image
|
466 |
fn=infer,
|
467 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
@@ -472,36 +419,30 @@ with gr.Blocks(css=css) as demo:
|
|
472 |
fn=lambda x, history: update_history(x[1], history),
|
473 |
inputs=[result, history_gallery],
|
474 |
outputs=history_gallery,
|
475 |
-
show_api=False
|
476 |
).then( # Show the "Use as Input Image" button
|
477 |
fn=lambda: gr.update(visible=True),
|
478 |
inputs=None,
|
479 |
outputs=use_as_input_button,
|
480 |
-
show_api=False
|
481 |
)
|
482 |
|
483 |
prompt_input.submit( # Clear the result
|
484 |
fn=clear_result,
|
485 |
inputs=None,
|
486 |
outputs=result,
|
487 |
-
show_api=False
|
488 |
).then( # Generate the new image
|
489 |
fn=infer,
|
490 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
491 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
492 |
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
493 |
outputs=result,
|
494 |
-
show_api=False
|
495 |
).then( # Update the history gallery
|
496 |
fn=lambda x, history: update_history(x[1], history),
|
497 |
inputs=[result, history_gallery],
|
498 |
outputs=history_gallery,
|
499 |
-
show_api=False
|
500 |
).then( # Show the "Use as Input Image" button
|
501 |
fn=lambda: gr.update(visible=True),
|
502 |
inputs=None,
|
503 |
outputs=use_as_input_button,
|
504 |
-
show_api=False
|
505 |
)
|
506 |
|
507 |
preview_button.click(
|
@@ -509,8 +450,7 @@ with gr.Blocks(css=css) as demo:
|
|
509 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, resize_option, custom_resize_percentage, alignment_dropdown,
|
510 |
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
511 |
outputs=preview_image,
|
512 |
-
queue=False
|
513 |
-
show_api=False
|
514 |
)
|
515 |
|
516 |
-
demo.queue(max_size=12).launch(share=False, show_error=True
|
|
|
169 |
return preview
|
170 |
|
171 |
@spaces.GPU(duration=24)
|
172 |
+
def infer(image, width, height, overlap_percentage, num_inference_steps, resize_option, custom_resize_percentage, prompt_input, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom):
|
173 |
+
background, mask = prepare_image_and_mask(image, width, height, overlap_percentage, resize_option, custom_resize_percentage, alignment, overlap_left, overlap_right, overlap_top, overlap_bottom)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
if not can_expand(background.width, background.height, width, height, alignment):
|
176 |
alignment = "Middle"
|
177 |
|
|
|
202 |
|
203 |
yield background, cnet_image
|
204 |
|
|
|
205 |
def clear_result():
|
206 |
"""Clears the result ImageSlider."""
|
207 |
return gr.update(value=None)
|
|
|
374 |
use_as_input_button.click(
|
375 |
fn=use_output_as_input,
|
376 |
inputs=[result],
|
377 |
+
outputs=[input_image]
|
|
|
378 |
)
|
379 |
|
380 |
target_ratio.change(
|
381 |
fn=preload_presets,
|
382 |
inputs=[target_ratio, width_slider, height_slider],
|
383 |
outputs=[width_slider, height_slider, settings_panel],
|
384 |
+
queue=False
|
|
|
385 |
)
|
386 |
|
387 |
width_slider.change(
|
388 |
fn=select_the_right_preset,
|
389 |
inputs=[width_slider, height_slider],
|
390 |
outputs=[target_ratio],
|
391 |
+
queue=False
|
|
|
392 |
)
|
393 |
|
394 |
height_slider.change(
|
395 |
fn=select_the_right_preset,
|
396 |
inputs=[width_slider, height_slider],
|
397 |
outputs=[target_ratio],
|
398 |
+
queue=False
|
|
|
399 |
)
|
400 |
|
401 |
resize_option.change(
|
402 |
fn=toggle_custom_resize_slider,
|
403 |
inputs=[resize_option],
|
404 |
outputs=[custom_resize_percentage],
|
405 |
+
queue=False
|
|
|
406 |
)
|
407 |
|
408 |
run_button.click( # Clear the result
|
409 |
fn=clear_result,
|
410 |
inputs=None,
|
411 |
outputs=result,
|
|
|
412 |
).then( # Generate the new image
|
413 |
fn=infer,
|
414 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
|
|
419 |
fn=lambda x, history: update_history(x[1], history),
|
420 |
inputs=[result, history_gallery],
|
421 |
outputs=history_gallery,
|
|
|
422 |
).then( # Show the "Use as Input Image" button
|
423 |
fn=lambda: gr.update(visible=True),
|
424 |
inputs=None,
|
425 |
outputs=use_as_input_button,
|
|
|
426 |
)
|
427 |
|
428 |
prompt_input.submit( # Clear the result
|
429 |
fn=clear_result,
|
430 |
inputs=None,
|
431 |
outputs=result,
|
|
|
432 |
).then( # Generate the new image
|
433 |
fn=infer,
|
434 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, num_inference_steps,
|
435 |
resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
|
436 |
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
437 |
outputs=result,
|
|
|
438 |
).then( # Update the history gallery
|
439 |
fn=lambda x, history: update_history(x[1], history),
|
440 |
inputs=[result, history_gallery],
|
441 |
outputs=history_gallery,
|
|
|
442 |
).then( # Show the "Use as Input Image" button
|
443 |
fn=lambda: gr.update(visible=True),
|
444 |
inputs=None,
|
445 |
outputs=use_as_input_button,
|
|
|
446 |
)
|
447 |
|
448 |
preview_button.click(
|
|
|
450 |
inputs=[input_image, width_slider, height_slider, overlap_percentage, resize_option, custom_resize_percentage, alignment_dropdown,
|
451 |
overlap_left, overlap_right, overlap_top, overlap_bottom],
|
452 |
outputs=preview_image,
|
453 |
+
queue=False
|
|
|
454 |
)
|
455 |
|
456 |
+
demo.queue(max_size=12).launch(share=False, show_error=True)
|
requirements.txt
CHANGED
@@ -1,12 +1,10 @@
|
|
1 |
torch==2.5.1
|
2 |
spaces==0.30.4
|
3 |
-
gradio
|
4 |
gradio-imageslider
|
5 |
numpy==1.26.4
|
6 |
transformers==4.45.0
|
7 |
accelerate==0.33.0
|
8 |
-
|
9 |
-
diffusers==0.32.2
|
10 |
-
huggingface-hub
|
11 |
fastapi<0.113.0
|
12 |
opencv-python
|
|
|
1 |
torch==2.5.1
|
2 |
spaces==0.30.4
|
3 |
+
gradio==4.42.0
|
4 |
gradio-imageslider
|
5 |
numpy==1.26.4
|
6 |
transformers==4.45.0
|
7 |
accelerate==0.33.0
|
8 |
+
diffusers==0.30.3
|
|
|
|
|
9 |
fastapi<0.113.0
|
10 |
opencv-python
|