Spaces:
Sleeping
Sleeping
| from PIL import Image | |
| from diffusers import StableDiffusionUpscalePipeline | |
| import torch | |
| from split_image import split | |
| import os | |
| import random | |
| def split_image(im, rows, cols, should_square, should_quiet=False): | |
| im_width, im_height = im.size | |
| row_width = int(im_width / cols) | |
| row_height = int(im_height / rows) | |
| name = "image" | |
| ext = ".png" | |
| name = os.path.basename(name) | |
| images = [] | |
| if should_square: | |
| min_dimension = min(im_width, im_height) | |
| max_dimension = max(im_width, im_height) | |
| if not should_quiet: | |
| print("Resizing image to a square...") | |
| print("Determining background color...") | |
| bg_color = split.determine_bg_color(im) | |
| if not should_quiet: | |
| print("Background color is... " + str(bg_color)) | |
| im_r = Image.new("RGBA" if ext == "png" else "RGB", | |
| (max_dimension, max_dimension), bg_color) | |
| offset = int((max_dimension - min_dimension) / 2) | |
| if im_width > im_height: | |
| im_r.paste(im, (0, offset)) | |
| else: | |
| im_r.paste(im, (offset, 0)) | |
| im = im_r | |
| row_width = int(max_dimension / cols) | |
| row_height = int(max_dimension / rows) | |
| n = 0 | |
| for i in range(0, rows): | |
| for j in range(0, cols): | |
| box = (j * row_width, i * row_height, j * row_width + | |
| row_width, i * row_height + row_height) | |
| outp = im.crop(box) | |
| outp_path = name + "_" + str(n) + ext | |
| if not should_quiet: | |
| print("Exporting image tile: " + outp_path) | |
| images.append(outp) | |
| n += 1 | |
| return [img for img in images] | |
| def upscale_image(img, rows, cols,seed,prompt,negative_prompt,xformers,cpu_offload,attention_slicing,enable_custom_sliders=False,guidance=7,iterations=50): | |
| model_id = "stabilityai/stable-diffusion-x4-upscaler" | |
| try: | |
| pipeline = StableDiffusionUpscalePipeline.from_pretrained(model_id, torch_dtype=torch.float16) | |
| except: | |
| pipeline = StableDiffusionUpscalePipeline.from_pretrained(model_id, torch_dtype=torch.float16, local_files_only=True) | |
| pipeline = pipeline.to("cuda") | |
| if xformers: | |
| pipeline.enable_xformers_memory_efficient_attention() | |
| else: | |
| pipeline.disable_xformers_memory_efficient_attention() | |
| if cpu_offload: | |
| try: | |
| pipeline.enable_sequential_cpu_offload() | |
| except: | |
| pass | |
| if attention_slicing: | |
| pipeline.enable_attention_slicing() | |
| else: | |
| pipeline.disable_attention_slicing() | |
| img = Image.fromarray(img) | |
| # load model and scheduler | |
| if seed==-1: | |
| generator = torch.manual_seed(random.randint(0, 9999999)) | |
| else: | |
| generator = torch.manual_seed(seed) | |
| original_width, original_height = img.size | |
| max_dimension = max(original_width, original_height) | |
| tiles = split_image(img, rows, cols, True, False) | |
| ups_tiles = [] | |
| i = 0 | |
| for x in tiles: | |
| i=i+1 | |
| if enable_custom_sliders: | |
| ups_tile = pipeline(prompt=prompt,negative_prompt=negative_prompt,guidance_scale=guidance, num_inference_steps=iterations, image=x.convert("RGB"),generator=generator).images[0] | |
| else: | |
| ups_tile = pipeline(prompt=prompt,negative_prompt=negative_prompt, image=x.convert("RGB"),generator=generator).images[0] | |
| ups_tiles.append(ups_tile) | |
| # Determine the size of the merged upscaled image | |
| total_width = 0 | |
| total_height = 0 | |
| side = 0 | |
| for ups_tile in ups_tiles: | |
| side = ups_tile.width | |
| break | |
| for x in tiles: | |
| tsize = x.width | |
| break | |
| ups_times = abs(side/tsize) | |
| new_size = (max_dimension * ups_times, max_dimension * ups_times) | |
| total_width = cols*side | |
| total_height = rows*side | |
| # Create a blank image with the calculated size | |
| merged_image = Image.new("RGB", (total_width, total_height)) | |
| # Paste each upscaled tile into the blank image | |
| current_width = 0 | |
| current_height = 0 | |
| maximum_width = cols*side | |
| for ups_tile in ups_tiles: | |
| merged_image.paste(ups_tile, (current_width, current_height)) | |
| current_width += ups_tile.width | |
| if current_width>=maximum_width: | |
| current_width = 0 | |
| current_height = current_height+side | |
| # Using the center of the image as pivot, crop the image to the original dimension times four | |
| crop_left = (new_size[0] - original_width * ups_times) // 2 | |
| crop_upper = (new_size[1] - original_height * ups_times) // 2 | |
| crop_right = crop_left + original_width * ups_times | |
| crop_lower = crop_upper + original_height * ups_times | |
| final_img = merged_image.crop((crop_left, crop_upper, crop_right, crop_lower)) | |
| # The resulting image should be identical to the original image in proportions / aspect ratio, with no loss of elements. | |
| # Save the merged image | |
| return final_img |