| |
|
|
| import logging |
| import torch |
| import comfy |
| from usdu_patch import usdu |
| from utils import tensor_to_pil, pil_to_tensor |
| from modules.processing import StableDiffusionProcessing |
| import modules.shared as shared |
| from modules.upscaler import UpscalerData |
|
|
| MAX_RESOLUTION = 8192 |
| |
| MODES = { |
| "Linear": usdu.USDUMode.LINEAR, |
| "Chess": usdu.USDUMode.CHESS, |
| "None": usdu.USDUMode.NONE, |
| } |
| |
| SEAM_FIX_MODES = { |
| "None": usdu.USDUSFMode.NONE, |
| "Band Pass": usdu.USDUSFMode.BAND_PASS, |
| "Half Tile": usdu.USDUSFMode.HALF_TILE, |
| "Half Tile + Intersections": usdu.USDUSFMode.HALF_TILE_PLUS_INTERSECTIONS, |
| } |
|
|
|
|
| def USDU_base_inputs(): |
| required = [ |
| ("image", ("IMAGE",)), |
| |
| ("model", ("MODEL",)), |
| ("positive", ("CONDITIONING",)), |
| ("negative", ("CONDITIONING",)), |
| ("vae", ("VAE",)), |
| ("upscale_by", ("FLOAT", {"default": 2, "min": 0.05, "max": 4, "step": 0.05})), |
| ("seed", ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff})), |
| ("steps", ("INT", {"default": 20, "min": 1, "max": 10000, "step": 1})), |
| ("cfg", ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0})), |
| ("sampler_name", (comfy.samplers.KSampler.SAMPLERS,)), |
| ("scheduler", (comfy.samplers.KSampler.SCHEDULERS,)), |
| ("denoise", ("FLOAT", {"default": 0.2, "min": 0.0, "max": 1.0, "step": 0.01})), |
| |
| ("upscale_model", ("UPSCALE_MODEL",)), |
| ("mode_type", (list(MODES.keys()),)), |
| ("tile_width", ("INT", {"default": 512, "min": 64, "max": MAX_RESOLUTION, "step": 8})), |
| ("tile_height", ("INT", {"default": 512, "min": 64, "max": MAX_RESOLUTION, "step": 8})), |
| ("mask_blur", ("INT", {"default": 8, "min": 0, "max": 64, "step": 1})), |
| ("tile_padding", ("INT", {"default": 32, "min": 0, "max": MAX_RESOLUTION, "step": 8})), |
| |
| ("seam_fix_mode", (list(SEAM_FIX_MODES.keys()),)), |
| ("seam_fix_denoise", ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01})), |
| ("seam_fix_width", ("INT", {"default": 64, "min": 0, "max": MAX_RESOLUTION, "step": 8})), |
| ("seam_fix_mask_blur", ("INT", {"default": 8, "min": 0, "max": 64, "step": 1})), |
| ("seam_fix_padding", ("INT", {"default": 16, "min": 0, "max": MAX_RESOLUTION, "step": 8})), |
| |
| ("force_uniform_tiles", ("BOOLEAN", {"default": True})), |
| ("tiled_decode", ("BOOLEAN", {"default": False})), |
| ] |
|
|
| optional = [] |
|
|
| return required, optional |
|
|
|
|
| def prepare_inputs(required: list, optional: list = None): |
| inputs = {} |
| if required: |
| inputs["required"] = {} |
| for name, type in required: |
| inputs["required"][name] = type |
| if optional: |
| inputs["optional"] = {} |
| for name, type in optional: |
| inputs["optional"][name] = type |
| return inputs |
|
|
|
|
| def remove_input(inputs: list, input_name: str): |
| for i, (n, _) in enumerate(inputs): |
| if n == input_name: |
| del inputs[i] |
| break |
|
|
|
|
| def rename_input(inputs: list, old_name: str, new_name: str): |
| for i, (n, t) in enumerate(inputs): |
| if n == old_name: |
| inputs[i] = (new_name, t) |
| break |
|
|
|
|
| class UltimateSDUpscale: |
| @classmethod |
| def INPUT_TYPES(s): |
| required, optional = USDU_base_inputs() |
| return prepare_inputs(required, optional) |
|
|
| RETURN_TYPES = ("IMAGE",) |
| FUNCTION = "upscale" |
| CATEGORY = "image/upscaling" |
|
|
| def upscale(self, image, model, positive, negative, vae, upscale_by, seed, |
| steps, cfg, sampler_name, scheduler, denoise, upscale_model, |
| mode_type, tile_width, tile_height, mask_blur, tile_padding, |
| seam_fix_mode, seam_fix_denoise, seam_fix_mask_blur, |
| seam_fix_width, seam_fix_padding, force_uniform_tiles, tiled_decode, |
| custom_sampler=None, custom_sigmas=None): |
| |
| self.tile_width = tile_width |
| self.tile_height = tile_height |
| self.mask_blur = mask_blur |
| self.tile_padding = tile_padding |
| self.seam_fix_width = seam_fix_width |
| self.seam_fix_denoise = seam_fix_denoise |
| self.seam_fix_padding = seam_fix_padding |
| self.seam_fix_mode = seam_fix_mode |
| self.mode_type = mode_type |
| self.upscale_by = upscale_by |
| self.seam_fix_mask_blur = seam_fix_mask_blur |
|
|
| |
| |
| |
|
|
| |
| |
| shared.sd_upscalers[0] = UpscalerData() |
| |
| shared.actual_upscaler = upscale_model |
|
|
| |
| shared.batch = [tensor_to_pil(image, i) for i in range(len(image))] |
| shared.batch_as_tensor = image |
|
|
| |
| sdprocessing = StableDiffusionProcessing( |
| shared.batch[0], model, positive, negative, vae, |
| seed, steps, cfg, sampler_name, scheduler, denoise, upscale_by, force_uniform_tiles, tiled_decode, |
| tile_width, tile_height, MODES[self.mode_type], SEAM_FIX_MODES[self.seam_fix_mode], |
| custom_sampler, custom_sigmas, |
| ) |
|
|
| |
| logger = logging.getLogger() |
| old_level = logger.getEffectiveLevel() |
| logger.setLevel(logging.CRITICAL + 1) |
| try: |
| |
| |
| |
| script = usdu.Script() |
| processed = script.run(p=sdprocessing, _=None, tile_width=self.tile_width, tile_height=self.tile_height, |
| mask_blur=self.mask_blur, padding=self.tile_padding, seams_fix_width=self.seam_fix_width, |
| seams_fix_denoise=self.seam_fix_denoise, seams_fix_padding=self.seam_fix_padding, |
| upscaler_index=0, save_upscaled_image=False, redraw_mode=MODES[self.mode_type], |
| save_seams_fix_image=False, seams_fix_mask_blur=self.seam_fix_mask_blur, |
| seams_fix_type=SEAM_FIX_MODES[self.seam_fix_mode], target_size_type=2, |
| custom_width=None, custom_height=None, custom_scale=self.upscale_by) |
|
|
| |
| images = [pil_to_tensor(img) for img in shared.batch] |
| tensor = torch.cat(images, dim=0) |
| return (tensor,) |
| finally: |
| |
| logger.setLevel(old_level) |
|
|
| class UltimateSDUpscaleNoUpscale(UltimateSDUpscale): |
| @classmethod |
| def INPUT_TYPES(s): |
| required, optional = USDU_base_inputs() |
| remove_input(required, "upscale_model") |
| remove_input(required, "upscale_by") |
| rename_input(required, "image", "upscaled_image") |
| return prepare_inputs(required, optional) |
|
|
| RETURN_TYPES = ("IMAGE",) |
| FUNCTION = "upscale" |
| CATEGORY = "image/upscaling" |
|
|
| def upscale(self, upscaled_image, model, positive, negative, vae, seed, |
| steps, cfg, sampler_name, scheduler, denoise, |
| mode_type, tile_width, tile_height, mask_blur, tile_padding, |
| seam_fix_mode, seam_fix_denoise, seam_fix_mask_blur, |
| seam_fix_width, seam_fix_padding, force_uniform_tiles, tiled_decode): |
| upscale_by = 1.0 |
| return super().upscale(upscaled_image, model, positive, negative, vae, upscale_by, seed, |
| steps, cfg, sampler_name, scheduler, denoise, None, |
| mode_type, tile_width, tile_height, mask_blur, tile_padding, |
| seam_fix_mode, seam_fix_denoise, seam_fix_mask_blur, |
| seam_fix_width, seam_fix_padding, force_uniform_tiles, tiled_decode) |
| |
| class UltimateSDUpscaleCustomSample(UltimateSDUpscale): |
| @classmethod |
| def INPUT_TYPES(s): |
| required, optional = USDU_base_inputs() |
| remove_input(required, "upscale_model") |
| optional.append(("upscale_model", ("UPSCALE_MODEL",))) |
| optional.append(("custom_sampler", ("SAMPLER",))) |
| optional.append(("custom_sigmas", ("SIGMAS",))) |
| return prepare_inputs(required, optional) |
| |
| RETURN_TYPES = ("IMAGE",) |
| FUNCTION = "upscale" |
| CATEGORY = "image/upscaling" |
|
|
| def upscale(self, image, model, positive, negative, vae, upscale_by, seed, |
| steps, cfg, sampler_name, scheduler, denoise, |
| mode_type, tile_width, tile_height, mask_blur, tile_padding, |
| seam_fix_mode, seam_fix_denoise, seam_fix_mask_blur, |
| seam_fix_width, seam_fix_padding, force_uniform_tiles, tiled_decode, |
| upscale_model=None, |
| custom_sampler=None, custom_sigmas=None): |
| return super().upscale(image, model, positive, negative, vae, upscale_by, seed, |
| steps, cfg, sampler_name, scheduler, denoise, upscale_model, |
| mode_type, tile_width, tile_height, mask_blur, tile_padding, |
| seam_fix_mode, seam_fix_denoise, seam_fix_mask_blur, |
| seam_fix_width, seam_fix_padding, force_uniform_tiles, tiled_decode, |
| custom_sampler, custom_sigmas) |
|
|
|
|
| |
| |
| NODE_CLASS_MAPPINGS = { |
| "UltimateSDUpscale": UltimateSDUpscale, |
| "UltimateSDUpscaleNoUpscale": UltimateSDUpscaleNoUpscale, |
| "UltimateSDUpscaleCustomSample": UltimateSDUpscaleCustomSample |
| } |
|
|
| |
| NODE_DISPLAY_NAME_MAPPINGS = { |
| "UltimateSDUpscale": "Ultimate SD Upscale", |
| "UltimateSDUpscaleNoUpscale": "Ultimate SD Upscale (No Upscale)", |
| "UltimateSDUpscaleCustomSample": "Ultimate SD Upscale (Custom Sample)" |
| } |
|
|