Files changed (1) hide show
  1. app.py +54 -39
app.py CHANGED
@@ -10,6 +10,7 @@ from pipeline_fill_sd_xl import StableDiffusionXLFillPipeline
10
  from PIL import Image, ImageDraw
11
  import numpy as np
12
 
 
13
  MODELS = {
14
  "RealVisXL V5.0 Lightning": "SG161222/RealVisXL_V5.0_Lightning",
15
  "Lustify Lightning": "GraydientPlatformAPI/lustify-lightning",
@@ -34,58 +35,63 @@ model.to(device="cuda", dtype=torch.float16)
34
  vae = AutoencoderKL.from_pretrained(
35
  "madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
36
  ).to("cuda")
37
- pipe = StableDiffusionXLFillPipeline.from_pretrained(
38
- "SG161222/RealVisXL_V5.0_Lightning",
39
- torch_dtype=torch.float16,
40
- vae=vae,
41
- controlnet=model,
42
- variant="fp16",
43
- )
44
- pipe = StableDiffusionXLFillPipeline.from_pretrained(
45
- "GraydientPlatformAPI/lustify-lightning",
46
- torch_dtype=torch.float16,
47
- vae=vae,
48
- controlnet=model,
49
- )
50
- pipe.scheduler = TCDScheduler.from_config(pipe.scheduler.config)
51
- pipe.to("cuda")
 
52
 
53
  @spaces.GPU(duration=12)
54
  def fill_image(prompt, image, model_selection, paste_back):
55
- print(f"Received image: {image}")
56
  if image is None:
57
  yield None, None
58
  return
59
-
 
 
60
  (
61
  prompt_embeds,
62
  negative_prompt_embeds,
63
  pooled_prompt_embeds,
64
  negative_pooled_prompt_embeds,
65
  ) = pipe.encode_prompt(prompt, "cuda", True)
 
66
  source = image["background"]
67
  mask = image["layers"][0]
68
  alpha_channel = mask.split()[3]
69
  binary_mask = alpha_channel.point(lambda p: p > 0 and 255)
 
70
  cnet_image = source.copy()
71
  cnet_image.paste(0, (0, 0), binary_mask)
72
-
73
- for image in pipe(
74
  prompt_embeds=prompt_embeds,
75
  negative_prompt_embeds=negative_prompt_embeds,
76
  pooled_prompt_embeds=pooled_prompt_embeds,
77
  negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
78
  image=cnet_image,
79
  ):
80
- yield image, cnet_image
81
-
82
  print(f"{model_selection=}")
83
  print(f"{paste_back=}")
 
84
  if paste_back:
85
- image = image.convert("RGBA")
86
- cnet_image.paste(image, (0, 0), binary_mask)
87
  else:
88
- cnet_image = image
 
89
  yield source, cnet_image
90
 
91
  def clear_result():
@@ -231,32 +237,42 @@ def outpaint(image, width, height, overlap_percentage, num_inference_steps, resi
231
  yield background, cnet_image
232
 
233
  @spaces.GPU(duration=12)
234
- 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):
 
 
 
 
235
  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)
236
  if not can_expand(background.width, background.height, width, height, alignment):
237
  alignment = "Middle"
 
238
  cnet_image = background.copy()
239
  cnet_image.paste(0, (0, 0), mask)
240
- final_prompt = f"{prompt_input} , high quality, 4k"
 
 
241
  (
242
  prompt_embeds,
243
  negative_prompt_embeds,
244
  pooled_prompt_embeds,
245
  negative_pooled_prompt_embeds,
246
  ) = pipe.encode_prompt(final_prompt, "cuda", True)
247
- for image in pipe(
 
248
  prompt_embeds=prompt_embeds,
249
  negative_prompt_embeds=negative_prompt_embeds,
250
  pooled_prompt_embeds=pooled_prompt_embeds,
251
  negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
252
  image=cnet_image,
253
- num_inference_steps=num_inference_steps
254
  ):
255
- yield cnet_image, image
256
- image = image.convert("RGBA")
257
- cnet_image.paste(image, (0, 0), mask)
 
258
  yield background, cnet_image
259
 
 
260
  def use_output_as_input(output_image):
261
  return gr.update(value=output_image[1])
262
 
@@ -466,6 +482,11 @@ with gr.Blocks(css=css, fill_height=True) as demo:
466
  visible=False
467
  )
468
  with gr.Column():
 
 
 
 
 
469
  preview_button = gr.Button("Preview alignment and mask")
470
  gr.Examples(
471
  examples=[
@@ -484,35 +505,30 @@ with gr.Blocks(css=css, fill_height=True) as demo:
484
  use_as_input_button_outpaint = gr.Button("Use as Input Image", visible=False)
485
  history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
486
  preview_image = gr.Image(label="Preview")
487
-
488
  target_ratio.change(
489
  fn=preload_presets,
490
  inputs=[target_ratio, width_slider, height_slider],
491
  outputs=[width_slider, height_slider, settings_panel],
492
  queue=False
493
  )
494
-
495
  width_slider.change(
496
  fn=select_the_right_preset,
497
  inputs=[width_slider, height_slider],
498
  outputs=[target_ratio],
499
  queue=False
500
  )
501
-
502
  height_slider.change(
503
  fn=select_the_right_preset,
504
  inputs=[width_slider, height_slider],
505
  outputs=[target_ratio],
506
  queue=False
507
  )
508
-
509
  resize_option.change(
510
  fn=toggle_custom_resize_slider,
511
  inputs=[resize_option],
512
  outputs=[custom_resize_percentage],
513
  queue=False
514
  )
515
-
516
  use_as_input_button_outpaint.click(
517
  fn=use_output_as_input,
518
  inputs=[result_outpaint],
@@ -526,7 +542,7 @@ with gr.Blocks(css=css, fill_height=True) as demo:
526
  fn=infer,
527
  inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
528
  resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
529
- overlap_left, overlap_right, overlap_top, overlap_bottom],
530
  outputs=[result_outpaint],
531
  ).then(
532
  fn=lambda x, history: update_history(x[1], history),
@@ -545,7 +561,7 @@ with gr.Blocks(css=css, fill_height=True) as demo:
545
  fn=infer,
546
  inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
547
  resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
548
- overlap_left, overlap_right, overlap_top, overlap_bottom],
549
  outputs=[result_outpaint],
550
  ).then(
551
  fn=lambda x, history: update_history(x[1], history),
@@ -563,5 +579,4 @@ with gr.Blocks(css=css, fill_height=True) as demo:
563
  outputs=[preview_image],
564
  queue=False
565
  )
566
-
567
  demo.launch(show_error=True)
 
10
  from PIL import Image, ImageDraw
11
  import numpy as np
12
 
13
+
14
  MODELS = {
15
  "RealVisXL V5.0 Lightning": "SG161222/RealVisXL_V5.0_Lightning",
16
  "Lustify Lightning": "GraydientPlatformAPI/lustify-lightning",
 
35
  vae = AutoencoderKL.from_pretrained(
36
  "madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16
37
  ).to("cuda")
38
+
39
+ pipe = None
40
+
41
+
42
+ def get_pipeline(model_name):
43
+ global pipe
44
+ if pipe is not None and pipe.config.model_name == MODELS[model_name]:
45
+ return pipe
46
+ pipe = StableDiffusionXLFillPipeline.from_pretrained(
47
+ MODELS[model_name],
48
+ torch_dtype=torch.float16,
49
+ vae=vae,
50
+ controlnet=model,
51
+ ).to("cuda")
52
+ pipe.scheduler = TCDScheduler.from_config(pipe.scheduler.config)
53
+ return pipe
54
 
55
  @spaces.GPU(duration=12)
56
  def fill_image(prompt, image, model_selection, paste_back):
 
57
  if image is None:
58
  yield None, None
59
  return
60
+
61
+ pipe = get_pipeline(model_selection)
62
+
63
  (
64
  prompt_embeds,
65
  negative_prompt_embeds,
66
  pooled_prompt_embeds,
67
  negative_pooled_prompt_embeds,
68
  ) = pipe.encode_prompt(prompt, "cuda", True)
69
+
70
  source = image["background"]
71
  mask = image["layers"][0]
72
  alpha_channel = mask.split()[3]
73
  binary_mask = alpha_channel.point(lambda p: p > 0 and 255)
74
+
75
  cnet_image = source.copy()
76
  cnet_image.paste(0, (0, 0), binary_mask)
77
+ for output_image in pipe(
 
78
  prompt_embeds=prompt_embeds,
79
  negative_prompt_embeds=negative_prompt_embeds,
80
  pooled_prompt_embeds=pooled_prompt_embeds,
81
  negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
82
  image=cnet_image,
83
  ):
84
+ yield output_image, cnet_image
85
+
86
  print(f"{model_selection=}")
87
  print(f"{paste_back=}")
88
+
89
  if paste_back:
90
+ output_image = output_image.convert("RGBA")
91
+ cnet_image.paste(output_image, (0, 0), binary_mask)
92
  else:
93
+ cnet_image = output_image
94
+
95
  yield source, cnet_image
96
 
97
  def clear_result():
 
237
  yield background, cnet_image
238
 
239
  @spaces.GPU(duration=12)
240
+ 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, model_selection):
241
+ if image is None:
242
+ yield None, None
243
+ return
244
+
245
  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)
246
  if not can_expand(background.width, background.height, width, height, alignment):
247
  alignment = "Middle"
248
+
249
  cnet_image = background.copy()
250
  cnet_image.paste(0, (0, 0), mask)
251
+ final_prompt = f"{prompt_input}, high quality, 4k"
252
+
253
+ pipe = get_pipeline(model_selection)
254
  (
255
  prompt_embeds,
256
  negative_prompt_embeds,
257
  pooled_prompt_embeds,
258
  negative_pooled_prompt_embeds,
259
  ) = pipe.encode_prompt(final_prompt, "cuda", True)
260
+
261
+ for output_image in pipe(
262
  prompt_embeds=prompt_embeds,
263
  negative_prompt_embeds=negative_prompt_embeds,
264
  pooled_prompt_embeds=pooled_prompt_embeds,
265
  negative_pooled_prompt_embeds=negative_pooled_prompt_embeds,
266
  image=cnet_image,
267
+ num_inference_steps=num_inference_steps,
268
  ):
269
+ yield cnet_image, output_image
270
+
271
+ output_image = output_image.convert("RGBA")
272
+ cnet_image.paste(output_image, (0, 0), mask)
273
  yield background, cnet_image
274
 
275
+
276
  def use_output_as_input(output_image):
277
  return gr.update(value=output_image[1])
278
 
 
482
  visible=False
483
  )
484
  with gr.Column():
485
+ out_model_selection = gr.Dropdown(
486
+ choices=list(MODELS.keys()),
487
+ value="RealVisXL V5.0 Lightning",
488
+ label="Model",
489
+ )
490
  preview_button = gr.Button("Preview alignment and mask")
491
  gr.Examples(
492
  examples=[
 
505
  use_as_input_button_outpaint = gr.Button("Use as Input Image", visible=False)
506
  history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
507
  preview_image = gr.Image(label="Preview")
 
508
  target_ratio.change(
509
  fn=preload_presets,
510
  inputs=[target_ratio, width_slider, height_slider],
511
  outputs=[width_slider, height_slider, settings_panel],
512
  queue=False
513
  )
 
514
  width_slider.change(
515
  fn=select_the_right_preset,
516
  inputs=[width_slider, height_slider],
517
  outputs=[target_ratio],
518
  queue=False
519
  )
 
520
  height_slider.change(
521
  fn=select_the_right_preset,
522
  inputs=[width_slider, height_slider],
523
  outputs=[target_ratio],
524
  queue=False
525
  )
 
526
  resize_option.change(
527
  fn=toggle_custom_resize_slider,
528
  inputs=[resize_option],
529
  outputs=[custom_resize_percentage],
530
  queue=False
531
  )
 
532
  use_as_input_button_outpaint.click(
533
  fn=use_output_as_input,
534
  inputs=[result_outpaint],
 
542
  fn=infer,
543
  inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
544
  resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
545
+ overlap_left, overlap_right, overlap_top, overlap_bottom, out_model_selection], # Add model_selection here
546
  outputs=[result_outpaint],
547
  ).then(
548
  fn=lambda x, history: update_history(x[1], history),
 
561
  fn=infer,
562
  inputs=[input_image_outpaint, width_slider, height_slider, overlap_percentage, num_inference_steps,
563
  resize_option, custom_resize_percentage, prompt_input, alignment_dropdown,
564
+ overlap_left, overlap_right, overlap_top, overlap_bottom, out_model_selection], # Add model_selection here
565
  outputs=[result_outpaint],
566
  ).then(
567
  fn=lambda x, history: update_history(x[1], history),
 
579
  outputs=[preview_image],
580
  queue=False
581
  )
 
582
  demo.launch(show_error=True)