postprocessing_split_oversized.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import math
  2. from modules import scripts_postprocessing, ui_components
  3. import gradio as gr
  4. def split_pic(image, inverse_xy, width, height, overlap_ratio):
  5. if inverse_xy:
  6. from_w, from_h = image.height, image.width
  7. to_w, to_h = height, width
  8. else:
  9. from_w, from_h = image.width, image.height
  10. to_w, to_h = width, height
  11. h = from_h * to_w // from_w
  12. if inverse_xy:
  13. image = image.resize((h, to_w))
  14. else:
  15. image = image.resize((to_w, h))
  16. split_count = math.ceil((h - to_h * overlap_ratio) / (to_h * (1.0 - overlap_ratio)))
  17. y_step = (h - to_h) / (split_count - 1)
  18. for i in range(split_count):
  19. y = int(y_step * i)
  20. if inverse_xy:
  21. splitted = image.crop((y, 0, y + to_h, to_w))
  22. else:
  23. splitted = image.crop((0, y, to_w, y + to_h))
  24. yield splitted
  25. class ScriptPostprocessingSplitOversized(scripts_postprocessing.ScriptPostprocessing):
  26. name = "Split oversized images"
  27. order = 4000
  28. def ui(self):
  29. with ui_components.InputAccordion(False, label="Split oversized images") as enable:
  30. with gr.Row():
  31. split_threshold = gr.Slider(label='Threshold', value=0.5, minimum=0.0, maximum=1.0, step=0.05, elem_id="postprocess_split_threshold")
  32. overlap_ratio = gr.Slider(label='Overlap ratio', value=0.2, minimum=0.0, maximum=0.9, step=0.05, elem_id="postprocess_overlap_ratio")
  33. return {
  34. "enable": enable,
  35. "split_threshold": split_threshold,
  36. "overlap_ratio": overlap_ratio,
  37. }
  38. def process(self, pp: scripts_postprocessing.PostprocessedImage, enable, split_threshold, overlap_ratio):
  39. if not enable:
  40. return
  41. width = pp.shared.target_width
  42. height = pp.shared.target_height
  43. if not width or not height:
  44. return
  45. if pp.image.height > pp.image.width:
  46. ratio = (pp.image.width * height) / (pp.image.height * width)
  47. inverse_xy = False
  48. else:
  49. ratio = (pp.image.height * width) / (pp.image.width * height)
  50. inverse_xy = True
  51. if ratio >= 1.0 or ratio > split_threshold:
  52. return
  53. result, *others = split_pic(pp.image, inverse_xy, width, height, overlap_ratio)
  54. pp.image = result
  55. pp.extra_images = [pp.create_copy(x) for x in others]