mirror of
				https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
				synced 2025-10-31 10:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			100 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from PIL import Image, ImageFilter, ImageOps
 | |
| 
 | |
| 
 | |
| def get_crop_region(mask, pad=0):
 | |
|     """finds a rectangular region that contains all masked ares in an image. Returns (x1, y1, x2, y2) coordinates of the rectangle.
 | |
|     For example, if a user has painted the top-right part of a 512x512 image", the result may be (256, 0, 512, 256)"""
 | |
| 
 | |
|     h, w = mask.shape
 | |
| 
 | |
|     crop_left = 0
 | |
|     for i in range(w):
 | |
|         if not (mask[:, i] == 0).all():
 | |
|             break
 | |
|         crop_left += 1
 | |
| 
 | |
|     crop_right = 0
 | |
|     for i in reversed(range(w)):
 | |
|         if not (mask[:, i] == 0).all():
 | |
|             break
 | |
|         crop_right += 1
 | |
| 
 | |
|     crop_top = 0
 | |
|     for i in range(h):
 | |
|         if not (mask[i] == 0).all():
 | |
|             break
 | |
|         crop_top += 1
 | |
| 
 | |
|     crop_bottom = 0
 | |
|     for i in reversed(range(h)):
 | |
|         if not (mask[i] == 0).all():
 | |
|             break
 | |
|         crop_bottom += 1
 | |
| 
 | |
|     return (
 | |
|         int(max(crop_left-pad, 0)),
 | |
|         int(max(crop_top-pad, 0)),
 | |
|         int(min(w - crop_right + pad, w)),
 | |
|         int(min(h - crop_bottom + pad, h))
 | |
|     )
 | |
| 
 | |
| 
 | |
| def expand_crop_region(crop_region, processing_width, processing_height, image_width, image_height):
 | |
|     """expands crop region get_crop_region() to match the ratio of the image the region will processed in; returns expanded region
 | |
|     for example, if user drew mask in a 128x32 region, and the dimensions for processing are 512x512, the region will be expanded to 128x128."""
 | |
| 
 | |
|     x1, y1, x2, y2 = crop_region
 | |
| 
 | |
|     ratio_crop_region = (x2 - x1) / (y2 - y1)
 | |
|     ratio_processing = processing_width / processing_height
 | |
| 
 | |
|     if ratio_crop_region > ratio_processing:
 | |
|         desired_height = (x2 - x1) / ratio_processing
 | |
|         desired_height_diff = int(desired_height - (y2-y1))
 | |
|         y1 -= desired_height_diff//2
 | |
|         y2 += desired_height_diff - desired_height_diff//2
 | |
|         if y2 >= image_height:
 | |
|             diff = y2 - image_height
 | |
|             y2 -= diff
 | |
|             y1 -= diff
 | |
|         if y1 < 0:
 | |
|             y2 -= y1
 | |
|             y1 -= y1
 | |
|         if y2 >= image_height:
 | |
|             y2 = image_height
 | |
|     else:
 | |
|         desired_width = (y2 - y1) * ratio_processing
 | |
|         desired_width_diff = int(desired_width - (x2-x1))
 | |
|         x1 -= desired_width_diff//2
 | |
|         x2 += desired_width_diff - desired_width_diff//2
 | |
|         if x2 >= image_width:
 | |
|             diff = x2 - image_width
 | |
|             x2 -= diff
 | |
|             x1 -= diff
 | |
|         if x1 < 0:
 | |
|             x2 -= x1
 | |
|             x1 -= x1
 | |
|         if x2 >= image_width:
 | |
|             x2 = image_width
 | |
| 
 | |
|     return x1, y1, x2, y2
 | |
| 
 | |
| 
 | |
| def fill(image, mask):
 | |
|     """fills masked regions with colors from image using blur. Not extremely effective."""
 | |
| 
 | |
|     image_mod = Image.new('RGBA', (image.width, image.height))
 | |
| 
 | |
|     image_masked = Image.new('RGBa', (image.width, image.height))
 | |
|     image_masked.paste(image.convert("RGBA").convert("RGBa"), mask=ImageOps.invert(mask.convert('L')))
 | |
| 
 | |
|     image_masked = image_masked.convert('RGBa')
 | |
| 
 | |
|     for radius, repeats in [(256, 1), (64, 1), (16, 2), (4, 4), (2, 2), (0, 1)]:
 | |
|         blurred = image_masked.filter(ImageFilter.GaussianBlur(radius)).convert('RGBA')
 | |
|         for _ in range(repeats):
 | |
|             image_mod.alpha_composite(blurred)
 | |
| 
 | |
|     return image_mod.convert("RGB")
 | |
| 
 | 
