from modules.AutoEncoders import VariationalAE from modules.sample import sampling from modules.UltimateSDUpscale import USDU_upscaler, image_util import torch from PIL import ImageFilter, ImageDraw, Image from enum import Enum import math # taken from https://github.com/ssitu/ComfyUI_UltimateSDUpscale state = USDU_upscaler.state class UnsupportedModel(Exception): """#### Exception raised for unsupported models.""" pass class StableDiffusionProcessing: """#### Class representing the processing of Stable Diffusion images.""" def __init__( self, init_img: Image.Image, model: torch.nn.Module, positive: str, negative: str, vae: VariationalAE.VAE, seed: int, steps: int, cfg: float, sampler_name: str, scheduler: str, denoise: float, upscale_by: float, uniform_tile_mode: bool, ): """ #### Initialize the StableDiffusionProcessing class. #### Args: - `init_img` (Image.Image): The initial image. - `model` (torch.nn.Module): The model. - `positive` (str): The positive prompt. - `negative` (str): The negative prompt. - `vae` (VariationalAE.VAE): The variational autoencoder. - `seed` (int): The seed. - `steps` (int): The number of steps. - `cfg` (float): The CFG scale. - `sampler_name` (str): The sampler name. - `scheduler` (str): The scheduler. - `denoise` (float): The denoise strength. - `upscale_by` (float): The upscale factor. - `uniform_tile_mode` (bool): Whether to use uniform tile mode. """ # Variables used by the USDU script self.init_images = [init_img] self.image_mask = None self.mask_blur = 0 self.inpaint_full_res_padding = 0 self.width = init_img.width self.height = init_img.height self.model = model self.positive = positive self.negative = negative self.vae = vae self.seed = seed self.steps = steps self.cfg = cfg self.sampler_name = sampler_name self.scheduler = scheduler self.denoise = denoise # Variables used only by this script self.init_size = init_img.width, init_img.height self.upscale_by = upscale_by self.uniform_tile_mode = uniform_tile_mode # Other required A1111 variables for the USDU script that is currently unused in this script self.extra_generation_params = {} class Processed: """#### Class representing the processed images.""" def __init__( self, p: StableDiffusionProcessing, images: list, seed: int, info: str ): """ #### Initialize the Processed class. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `images` (list): The list of images. - `seed` (int): The seed. - `info` (str): The information string. """ self.images = images self.seed = seed self.info = info def infotext(self, p: StableDiffusionProcessing, index: int) -> str: """ #### Get the information text. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `index` (int): The index. #### Returns: - `str`: The information text. """ return None def fix_seed(p: StableDiffusionProcessing) -> None: """ #### Fix the seed for reproducibility. #### Args: - `p` (StableDiffusionProcessing): The processing object. """ pass def process_images(p: StableDiffusionProcessing, pipeline: bool = False) -> Processed: """ #### Process the images. #### Args: - `p` (StableDiffusionProcessing): The processing object. #### Returns: - `Processed`: The processed images. """ # Where the main image generation happens in A1111 # Setup image_mask = p.image_mask.convert("L") init_image = p.init_images[0] # Locate the white region of the mask outlining the tile and add padding crop_region = image_util.get_crop_region(image_mask, p.inpaint_full_res_padding) x1, y1, x2, y2 = crop_region crop_width = x2 - x1 crop_height = y2 - y1 crop_ratio = crop_width / crop_height p_ratio = p.width / p.height if crop_ratio > p_ratio: target_width = crop_width target_height = round(crop_width / p_ratio) else: target_width = round(crop_height * p_ratio) target_height = crop_height crop_region, _ = image_util.expand_crop( crop_region, image_mask.width, image_mask.height, target_width, target_height, ) tile_size = p.width, p.height # Blur the mask if p.mask_blur > 0: image_mask = image_mask.filter(ImageFilter.GaussianBlur(p.mask_blur)) # Crop the images to get the tiles that will be used for generation tiles = [img.crop(crop_region) for img in USDU_upscaler.batch] # Assume the same size for all images in the batch initial_tile_size = tiles[0].size # Resize if necessary for i, tile in enumerate(tiles): if tile.size != tile_size: tiles[i] = tile.resize(tile_size, Image.Resampling.LANCZOS) # Crop conditioning positive_cropped = image_util.crop_cond( p.positive, crop_region, p.init_size, init_image.size, tile_size ) negative_cropped = image_util.crop_cond( p.negative, crop_region, p.init_size, init_image.size, tile_size ) # Encode the image vae_encoder = VariationalAE.VAEEncode() batched_tiles = torch.cat([image_util.pil_to_tensor(tile) for tile in tiles], dim=0) (latent,) = vae_encoder.encode(p.vae, batched_tiles) # Generate samples (samples,) = sampling.common_ksampler( p.model, p.seed, p.steps, p.cfg, p.sampler_name, p.scheduler, positive_cropped, negative_cropped, latent, denoise=p.denoise, pipeline=pipeline ) # Decode the sample vae_decoder = VariationalAE.VAEDecode() (decoded,) = vae_decoder.decode(p.vae, samples) # Convert the sample to a PIL image tiles_sampled = [image_util.tensor_to_pil(decoded, i) for i in range(len(decoded))] for i, tile_sampled in enumerate(tiles_sampled): init_image = USDU_upscaler.batch[i] # Resize back to the original size if tile_sampled.size != initial_tile_size: tile_sampled = tile_sampled.resize( initial_tile_size, Image.Resampling.LANCZOS ) # Put the tile into position image_tile_only = Image.new("RGBA", init_image.size) image_tile_only.paste(tile_sampled, crop_region[:2]) # Add the mask as an alpha channel # Must make a copy due to the possibility of an edge becoming black temp = image_tile_only.copy() image_mask = image_mask.resize(temp.size) temp.putalpha(image_mask) temp.putalpha(image_mask) image_tile_only.paste(temp, image_tile_only) # Add back the tile to the initial image according to the mask in the alpha channel result = init_image.convert("RGBA") result.alpha_composite(image_tile_only) # Convert back to RGB result = result.convert("RGB") USDU_upscaler.batch[i] = result processed = Processed(p, [USDU_upscaler.batch[0]], p.seed, None) return processed class USDUMode(Enum): """#### Enum representing the modes for Ultimate SD Upscale.""" LINEAR = 0 CHESS = 1 NONE = 2 class USDUSFMode(Enum): """#### Enum representing the seam fix modes for Ultimate SD Upscale.""" NONE = 0 BAND_PASS = 1 HALF_TILE = 2 HALF_TILE_PLUS_INTERSECTIONS = 3 class USDUpscaler: """#### Class representing the Ultimate SD Upscaler.""" def __init__( self, p: StableDiffusionProcessing, image: Image.Image, upscaler_index: int, save_redraw: bool, save_seams_fix: bool, tile_width: int, tile_height: int, ) -> None: """ #### Initialize the USDUpscaler class. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `upscaler_index` (int): The upscaler index. - `save_redraw` (bool): Whether to save the redraw. - `save_seams_fix` (bool): Whether to save the seams fix. - `tile_width` (int): The tile width. - `tile_height` (int): The tile height. """ self.p: StableDiffusionProcessing = p self.image: Image = image self.scale_factor = math.ceil( max(p.width, p.height) / max(image.width, image.height) ) self.upscaler = USDU_upscaler.sd_upscalers[upscaler_index] self.redraw = USDURedraw() self.redraw.save = save_redraw self.redraw.tile_width = tile_width if tile_width > 0 else tile_height self.redraw.tile_height = tile_height if tile_height > 0 else tile_width self.seams_fix = USDUSeamsFix() self.seams_fix.save = save_seams_fix self.seams_fix.tile_width = tile_width if tile_width > 0 else tile_height self.seams_fix.tile_height = tile_height if tile_height > 0 else tile_width self.initial_info = None self.rows = math.ceil(self.p.height / self.redraw.tile_height) self.cols = math.ceil(self.p.width / self.redraw.tile_width) def get_factor(self, num: int) -> int: """ #### Get the factor for a given number. #### Args: - `num` (int): The number. #### Returns: - `int`: The factor. """ if num == 1: return 2 if num % 4 == 0: return 4 if num % 3 == 0: return 3 if num % 2 == 0: return 2 return 0 def get_factors(self) -> None: """ #### Get the list of scale factors. """ scales = [] current_scale = 1 current_scale_factor = self.get_factor(self.scale_factor) while current_scale < self.scale_factor: current_scale_factor = self.get_factor(self.scale_factor // current_scale) scales.append(current_scale_factor) current_scale = current_scale * current_scale_factor self.scales = enumerate(scales) def upscale(self) -> None: """ #### Upscale the image. """ # Log info print(f"Canva size: {self.p.width}x{self.p.height}") print(f"Image size: {self.image.width}x{self.image.height}") print(f"Scale factor: {self.scale_factor}") # Get list with scale factors self.get_factors() # Upscaling image over all factors for index, value in self.scales: print(f"Upscaling iteration {index + 1} with scale factor {value}") self.image = self.upscaler.scaler.upscale( self.image, value, self.upscaler.data_path ) # Resize image to set values self.image = self.image.resize( (self.p.width, self.p.height), resample=Image.LANCZOS ) def setup_redraw(self, redraw_mode: int, padding: int, mask_blur: int) -> None: """ #### Set up the redraw. #### Args: - `redraw_mode` (int): The redraw mode. - `padding` (int): The padding. - `mask_blur` (int): The mask blur. """ self.redraw.mode = USDUMode(redraw_mode) self.redraw.enabled = self.redraw.mode != USDUMode.NONE self.redraw.padding = padding self.p.mask_blur = mask_blur def setup_seams_fix( self, padding: int, denoise: float, mask_blur: int, width: int, mode: int ) -> None: """ #### Set up the seams fix. #### Args: - `padding` (int): The padding. - `denoise` (float): The denoise strength. - `mask_blur` (int): The mask blur. - `width` (int): The width. - `mode` (int): The mode. """ self.seams_fix.padding = padding self.seams_fix.denoise = denoise self.seams_fix.mask_blur = mask_blur self.seams_fix.width = width self.seams_fix.mode = USDUSFMode(mode) self.seams_fix.enabled = self.seams_fix.mode != USDUSFMode.NONE def calc_jobs_count(self) -> None: """ #### Calculate the number of jobs. """ redraw_job_count = (self.rows * self.cols) if self.redraw.enabled else 0 seams_job_count = self.rows * (self.cols - 1) + (self.rows - 1) * self.cols global state state.job_count = redraw_job_count + seams_job_count def print_info(self) -> None: """ #### Print the information. """ print(f"Tile size: {self.redraw.tile_width}x{self.redraw.tile_height}") print(f"Tiles amount: {self.rows * self.cols}") print(f"Grid: {self.rows}x{self.cols}") print(f"Redraw enabled: {self.redraw.enabled}") print(f"Seams fix mode: {self.seams_fix.mode.name}") def add_extra_info(self) -> None: """ #### Add extra information. """ self.p.extra_generation_params["Ultimate SD upscale upscaler"] = ( self.upscaler.name ) self.p.extra_generation_params["Ultimate SD upscale tile_width"] = ( self.redraw.tile_width ) self.p.extra_generation_params["Ultimate SD upscale tile_height"] = ( self.redraw.tile_height ) self.p.extra_generation_params["Ultimate SD upscale mask_blur"] = ( self.p.mask_blur ) self.p.extra_generation_params["Ultimate SD upscale padding"] = ( self.redraw.padding ) def process(self, pipeline) -> None: """ #### Process the image. """ USDU_upscaler.state.begin() self.calc_jobs_count() self.result_images = [] if self.redraw.enabled: self.image = self.redraw.start(self.p, self.image, self.rows, self.cols, pipeline) self.initial_info = self.redraw.initial_info self.result_images.append(self.image) if self.seams_fix.enabled: self.image = self.seams_fix.start(self.p, self.image, self.rows, self.cols, pipeline) self.initial_info = self.seams_fix.initial_info self.result_images.append(self.image) USDU_upscaler.state.end() class USDURedraw: """#### Class representing the redraw functionality for Ultimate SD Upscale.""" def init_draw(self, p: StableDiffusionProcessing, width: int, height: int) -> tuple: """ #### Initialize the draw. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `width` (int): The width. - `height` (int): The height. #### Returns: - `tuple`: The mask and draw objects. """ p.inpaint_full_res = True p.inpaint_full_res_padding = self.padding p.width = math.ceil((self.tile_width + self.padding) / 64) * 64 p.height = math.ceil((self.tile_height + self.padding) / 64) * 64 mask = Image.new("L", (width, height), "black") draw = ImageDraw.Draw(mask) return mask, draw def calc_rectangle(self, xi: int, yi: int) -> tuple: """ #### Calculate the rectangle coordinates. #### Args: - `xi` (int): The x index. - `yi` (int): The y index. #### Returns: - `tuple`: The rectangle coordinates. """ x1 = xi * self.tile_width y1 = yi * self.tile_height x2 = xi * self.tile_width + self.tile_width y2 = yi * self.tile_height + self.tile_height return x1, y1, x2, y2 def linear_process( self, p: StableDiffusionProcessing, image: Image.Image, rows: int, cols: int, pipeline: bool = False ) -> Image.Image: """ #### Perform linear processing. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `rows` (int): The number of rows. - `cols` (int): The number of columns. #### Returns: - `Image.Image`: The processed image. """ global state mask, draw = self.init_draw(p, image.width, image.height) for yi in range(rows): for xi in range(cols): if state.interrupted: break draw.rectangle(self.calc_rectangle(xi, yi), fill="white") p.init_images = [image] p.image_mask = mask processed = process_images(p, pipeline) draw.rectangle(self.calc_rectangle(xi, yi), fill="black") if len(processed.images) > 0: image = processed.images[0] p.width = image.width p.height = image.height self.initial_info = processed.infotext(p, 0) return image def start(self, p: StableDiffusionProcessing, image: Image.Image, rows: int, cols: int, pipeline: bool = False) -> Image.Image: """#### Start the redraw. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `rows` (int): The number of rows. - `cols` (int): The number of columns. #### Returns: - `Image.Image`: The processed image. """ self.initial_info = None return self.linear_process(p, image, rows, cols, pipeline=pipeline) class USDUSeamsFix: """#### Class representing the seams fix functionality for Ultimate SD Upscale.""" def init_draw(self, p: StableDiffusionProcessing) -> None: """#### Initialize the draw. #### Args: - `p` (StableDiffusionProcessing): The processing object. """ self.initial_info = None p.width = math.ceil((self.tile_width + self.padding) / 64) * 64 p.height = math.ceil((self.tile_height + self.padding) / 64) * 64 def half_tile_process( self, p: StableDiffusionProcessing, image: Image.Image, rows: int, cols: int, pipeline: bool = False ) -> Image.Image: """#### Perform half-tile processing. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `rows` (int): The number of rows. - `cols` (int): The number of columns. #### Returns: - `Image.Image`: The processed image. """ global state self.init_draw(p) processed = None gradient = Image.linear_gradient("L") row_gradient = Image.new("L", (self.tile_width, self.tile_height), "black") row_gradient.paste( gradient.resize( (self.tile_width, self.tile_height // 2), resample=Image.BICUBIC ), (0, 0), ) row_gradient.paste( gradient.rotate(180).resize( (self.tile_width, self.tile_height // 2), resample=Image.BICUBIC ), (0, self.tile_height // 2), ) col_gradient = Image.new("L", (self.tile_width, self.tile_height), "black") col_gradient.paste( gradient.rotate(90).resize( (self.tile_width // 2, self.tile_height), resample=Image.BICUBIC ), (0, 0), ) col_gradient.paste( gradient.rotate(270).resize( (self.tile_width // 2, self.tile_height), resample=Image.BICUBIC ), (self.tile_width // 2, 0), ) p.denoising_strength = self.denoise p.mask_blur = self.mask_blur for yi in range(rows - 1): for xi in range(cols): p.width = self.tile_width p.height = self.tile_height p.inpaint_full_res = True p.inpaint_full_res_padding = self.padding mask = Image.new("L", (image.width, image.height), "black") mask.paste( row_gradient, ( xi * self.tile_width, yi * self.tile_height + self.tile_height // 2, ), ) p.init_images = [image] p.image_mask = mask processed = process_images(p, pipeline) if len(processed.images) > 0: image = processed.images[0] for yi in range(rows): for xi in range(cols - 1): p.width = self.tile_width p.height = self.tile_height p.inpaint_full_res = True p.inpaint_full_res_padding = self.padding mask = Image.new("L", (image.width, image.height), "black") mask.paste( col_gradient, ( xi * self.tile_width + self.tile_width // 2, yi * self.tile_height, ), ) p.init_images = [image] p.image_mask = mask processed = process_images(p, pipeline) if len(processed.images) > 0: image = processed.images[0] p.width = image.width p.height = image.height if processed is not None: self.initial_info = processed.infotext(p, 0) return image def start( self, p: StableDiffusionProcessing, image: Image.Image, rows: int, cols: int, pipeline: bool = False ) -> Image.Image: """#### Start the seams fix process. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `rows` (int): The number of rows. - `cols` (int): The number of columns. #### Returns: - `Image.Image`: The processed image. """ return self.half_tile_process(p, image, rows, cols, pipeline=pipeline) class Script(USDU_upscaler.Script): """#### Class representing the script for Ultimate SD Upscale.""" def run( self, p: StableDiffusionProcessing, _: None, tile_width: int, tile_height: int, mask_blur: int, padding: int, seams_fix_width: int, seams_fix_denoise: float, seams_fix_padding: int, upscaler_index: int, save_upscaled_image: bool, redraw_mode: int, save_seams_fix_image: bool, seams_fix_mask_blur: int, seams_fix_type: int, target_size_type: int, custom_width: int, custom_height: int, custom_scale: float, pipeline: bool = False, ) -> Processed: """#### Run the script. #### Args: - `p` (StableDiffusionProcessing): The processing object. - `_` (None): Unused parameter. - `tile_width` (int): The tile width. - `tile_height` (int): The tile height. - `mask_blur` (int): The mask blur. - `padding` (int): The padding. - `seams_fix_width` (int): The seams fix width. - `seams_fix_denoise` (float): The seams fix denoise strength. - `seams_fix_padding` (int): The seams fix padding. - `upscaler_index` (int): The upscaler index. - `save_upscaled_image` (bool): Whether to save the upscaled image. - `redraw_mode` (int): The redraw mode. - `save_seams_fix_image` (bool): Whether to save the seams fix image. - `seams_fix_mask_blur` (int): The seams fix mask blur. - `seams_fix_type` (int): The seams fix type. - `target_size_type` (int): The target size type. - `custom_width` (int): The custom width. - `custom_height` (int): The custom height. - `custom_scale` (float): The custom scale. #### Returns: - `Processed`: The processed images. """ # Init fix_seed(p) USDU_upscaler.torch_gc() p.do_not_save_grid = True p.do_not_save_samples = True p.inpaint_full_res = False p.inpainting_fill = 1 p.n_iter = 1 p.batch_size = 1 seed = p.seed # Init image init_img = p.init_images[0] init_img = image_util.flatten( init_img, USDU_upscaler.opts.img2img_background_color ) p.width = math.ceil((init_img.width * custom_scale) / 64) * 64 p.height = math.ceil((init_img.height * custom_scale) / 64) * 64 # Upscaling upscaler = USDUpscaler( p, init_img, upscaler_index, save_upscaled_image, save_seams_fix_image, tile_width, tile_height, ) upscaler.upscale() # Drawing upscaler.setup_redraw(redraw_mode, padding, mask_blur) upscaler.setup_seams_fix( seams_fix_padding, seams_fix_denoise, seams_fix_mask_blur, seams_fix_width, seams_fix_type, ) upscaler.print_info() upscaler.add_extra_info() upscaler.process(pipeline=pipeline) result_images = upscaler.result_images return Processed( p, result_images, seed, upscaler.initial_info if upscaler.initial_info is not None else "", ) # Upscaler old_init = USDUpscaler.__init__ def new_init( self: USDUpscaler, p: StableDiffusionProcessing, image: Image.Image, upscaler_index: int, save_redraw: bool, save_seams_fix: bool, tile_width: int, tile_height: int, ) -> None: """#### Initialize the USDUpscaler class with new settings. #### Args: - `self` (USDUpscaler): The USDUpscaler instance. - `p` (StableDiffusionProcessing): The processing object. - `image` (Image.Image): The image. - `upscaler_index` (int): The upscaler index. - `save_redraw` (bool): Whether to save the redraw. - `save_seams_fix` (bool): Whether to save the seams fix. - `tile_width` (int): The tile width. - `tile_height` (int): The tile height. """ p.width = math.ceil((image.width * p.upscale_by) / 8) * 8 p.height = math.ceil((image.height * p.upscale_by) / 8) * 8 old_init( self, p, image, upscaler_index, save_redraw, save_seams_fix, tile_width, tile_height, ) USDUpscaler.__init__ = new_init # Redraw old_setup_redraw = USDURedraw.init_draw def new_setup_redraw( self: USDURedraw, p: StableDiffusionProcessing, width: int, height: int ) -> tuple: """#### Set up the redraw with new settings. #### Args: - `self` (USDURedraw): The USDURedraw instance. - `p` (StableDiffusionProcessing): The processing object. - `width` (int): The width. - `height` (int): The height. #### Returns: - `tuple`: The mask and draw objects. """ mask, draw = old_setup_redraw(self, p, width, height) p.width = math.ceil((self.tile_width + self.padding) / 8) * 8 p.height = math.ceil((self.tile_height + self.padding) / 8) * 8 return mask, draw USDURedraw.init_draw = new_setup_redraw # Seams fix old_setup_seams_fix = USDUSeamsFix.init_draw def new_setup_seams_fix(self: USDUSeamsFix, p: StableDiffusionProcessing) -> None: """#### Set up the seams fix with new settings. #### Args: - `self` (USDUSeamsFix): The USDUSeamsFix instance. - `p` (StableDiffusionProcessing): The processing object. """ old_setup_seams_fix(self, p) p.width = math.ceil((self.tile_width + self.padding) / 8) * 8 p.height = math.ceil((self.tile_height + self.padding) / 8) * 8 USDUSeamsFix.init_draw = new_setup_seams_fix # Make the script upscale on a batch of images instead of one image old_upscale = USDUpscaler.upscale def new_upscale(self: USDUpscaler) -> None: """#### Upscale a batch of images. #### Args: - `self` (USDUpscaler): The USDUpscaler instance. """ old_upscale(self) USDU_upscaler.batch = [self.image] + [ img.resize((self.p.width, self.p.height), resample=Image.LANCZOS) for img in USDU_upscaler.batch[1:] ] USDUpscaler.upscale = new_upscale MAX_RESOLUTION = 8192 # The modes available for Ultimate SD Upscale MODES = { "Linear": USDUMode.LINEAR, "Chess": USDUMode.CHESS, "None": USDUMode.NONE, } # The seam fix modes SEAM_FIX_MODES = { "None": USDUSFMode.NONE, "Band Pass": USDUSFMode.BAND_PASS, "Half Tile": USDUSFMode.HALF_TILE, "Half Tile + Intersections": USDUSFMode.HALF_TILE_PLUS_INTERSECTIONS, } class UltimateSDUpscale: """#### Class representing the Ultimate SD Upscale functionality.""" def upscale( self, image: torch.Tensor, model: torch.nn.Module, positive: str, negative: str, vae: VariationalAE.VAE, upscale_by: float, seed: int, steps: int, cfg: float, sampler_name: str, scheduler: str, denoise: float, upscale_model: any, mode_type: str, tile_width: int, tile_height: int, mask_blur: int, tile_padding: int, seam_fix_mode: str, seam_fix_denoise: float, seam_fix_mask_blur: int, seam_fix_width: int, seam_fix_padding: int, force_uniform_tiles: bool, pipeline: bool = False, ) -> tuple: """#### Upscale the image. #### Args: - `image` (torch.Tensor): The image tensor. - `model` (torch.nn.Module): The model. - `positive` (str): The positive prompt. - `negative` (str): The negative prompt. - `vae` (VariationalAE.VAE): The variational autoencoder. - `upscale_by` (float): The upscale factor. - `seed` (int): The seed. - `steps` (int): The number of steps. - `cfg` (float): The CFG scale. - `sampler_name` (str): The sampler name. - `scheduler` (str): The scheduler. - `denoise` (float): The denoise strength. - `upscale_model` (any): The upscale model. - `mode_type` (str): The mode type. - `tile_width` (int): The tile width. - `tile_height` (int): The tile height. - `mask_blur` (int): The mask blur. - `tile_padding` (int): The tile padding. - `seam_fix_mode` (str): The seam fix mode. - `seam_fix_denoise` (float): The seam fix denoise strength. - `seam_fix_mask_blur` (int): The seam fix mask blur. - `seam_fix_width` (int): The seam fix width. - `seam_fix_padding` (int): The seam fix padding. - `force_uniform_tiles` (bool): Whether to force uniform tiles. #### Returns: - `tuple`: The resulting tensor. """ # Set up A1111 patches # Upscaler # An object that the script works with USDU_upscaler.sd_upscalers[0] = USDU_upscaler.UpscalerData() # Where the actual upscaler is stored, will be used when the script upscales using the Upscaler in UpscalerData USDU_upscaler.actual_upscaler = upscale_model # Set the batch of images USDU_upscaler.batch = [image_util.tensor_to_pil(image, i) for i in range(len(image))] # Processing sdprocessing = StableDiffusionProcessing( image_util.tensor_to_pil(image), model, positive, negative, vae, seed, steps, cfg, sampler_name, scheduler, denoise, upscale_by, force_uniform_tiles, ) # Running the script script = Script() script.run( p=sdprocessing, _=None, tile_width=tile_width, tile_height=tile_height, mask_blur=mask_blur, padding=tile_padding, seams_fix_width=seam_fix_width, seams_fix_denoise=seam_fix_denoise, seams_fix_padding=seam_fix_padding, upscaler_index=0, save_upscaled_image=False, redraw_mode=MODES[mode_type], save_seams_fix_image=False, seams_fix_mask_blur=seam_fix_mask_blur, seams_fix_type=SEAM_FIX_MODES[seam_fix_mode], target_size_type=2, custom_width=None, custom_height=None, custom_scale=upscale_by, pipeline=pipeline, ) # Return the resulting images images = [image_util.pil_to_tensor(img) for img in USDU_upscaler.batch] tensor = torch.cat(images, dim=0) return (tensor,)