mirror of
https://github.com/Coyote-A/ultimate-upscale-for-automatic1111.git
synced 2026-01-26 19:29:51 +00:00
Fixed image saving duplicating the prompt by number of tiles and using the grid format rather than image format
556 lines
23 KiB
Python
556 lines
23 KiB
Python
import math
|
|
import gradio as gr
|
|
from PIL import Image, ImageDraw, ImageOps
|
|
from modules import processing, shared, images, devices, scripts
|
|
from modules.processing import StableDiffusionProcessing
|
|
from modules.processing import Processed
|
|
from modules.shared import opts, state
|
|
from enum import Enum
|
|
|
|
class USDUMode(Enum):
|
|
LINEAR = 0
|
|
CHESS = 1
|
|
NONE = 2
|
|
|
|
class USDUSFMode(Enum):
|
|
NONE = 0
|
|
BAND_PASS = 1
|
|
HALF_TILE = 2
|
|
HALF_TILE_PLUS_INTERSECTIONS = 3
|
|
|
|
class USDUpscaler():
|
|
|
|
def __init__(self, p, image, upscaler_index:int, save_redraw, save_seams_fix, tile_width, tile_height) -> None:
|
|
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 = shared.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):
|
|
# Its just return, don't need elif
|
|
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):
|
|
scales = []
|
|
current_scale = 1
|
|
current_scale_factor = self.get_factor(self.scale_factor)
|
|
while current_scale_factor == 0:
|
|
self.scale_factor += 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
|
|
if current_scale_factor == 0:
|
|
break
|
|
self.scales = enumerate(scales)
|
|
|
|
def upscale(self):
|
|
# 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}")
|
|
# Check upscaler is not empty
|
|
if self.upscaler.name == "None":
|
|
self.image = self.image.resize((self.p.width, self.p.height), resample=Image.LANCZOS)
|
|
return
|
|
# 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, padding, 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, denoise, mask_blur, width, 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 save_image(self):
|
|
if type(self.p.prompt) != list:
|
|
images.save_image(self.image, self.p.outpath_samples, "", self.p.seed, self.p.prompt, opts.samples_format, info=self.initial_info, p=self.p)
|
|
else:
|
|
images.save_image(self.image, self.p.outpath_samples, "", self.p.seed, self.p.prompt[0], opts.samples_format, info=self.initial_info, p=self.p)
|
|
|
|
def calc_jobs_count(self):
|
|
redraw_job_count = (self.rows * self.cols) if self.redraw.enabled else 0
|
|
seams_job_count = 0
|
|
if self.seams_fix.mode == USDUSFMode.BAND_PASS:
|
|
seams_job_count = self.rows + self.cols - 2
|
|
elif self.seams_fix.mode == USDUSFMode.HALF_TILE:
|
|
seams_job_count = self.rows * (self.cols - 1) + (self.rows - 1) * self.cols
|
|
elif self.seams_fix.mode == USDUSFMode.HALF_TILE_PLUS_INTERSECTIONS:
|
|
seams_job_count = self.rows * (self.cols - 1) + (self.rows - 1) * self.cols + (self.rows - 1) * (self.cols - 1)
|
|
|
|
state.job_count = redraw_job_count + seams_job_count
|
|
|
|
def print_info(self):
|
|
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):
|
|
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):
|
|
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)
|
|
self.initial_info = self.redraw.initial_info
|
|
self.result_images.append(self.image)
|
|
if self.redraw.save:
|
|
self.save_image()
|
|
|
|
if self.seams_fix.enabled:
|
|
self.image = self.seams_fix.start(self.p, self.image, self.rows, self.cols)
|
|
self.initial_info = self.seams_fix.initial_info
|
|
self.result_images.append(self.image)
|
|
if self.seams_fix.save:
|
|
self.save_image()
|
|
state.end()
|
|
|
|
class USDURedraw():
|
|
|
|
def init_draw(self, p, width, height):
|
|
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, yi):
|
|
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, image, rows, cols):
|
|
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 = processing.process_images(p)
|
|
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 chess_process(self, p, image, rows, cols):
|
|
mask, draw = self.init_draw(p, image.width, image.height)
|
|
tiles = []
|
|
# calc tiles colors
|
|
for yi in range(rows):
|
|
for xi in range(cols):
|
|
if state.interrupted:
|
|
break
|
|
if xi == 0:
|
|
tiles.append([])
|
|
color = xi % 2 == 0
|
|
if yi > 0 and yi % 2 != 0:
|
|
color = not color
|
|
tiles[yi].append(color)
|
|
|
|
for yi in range(len(tiles)):
|
|
for xi in range(len(tiles[yi])):
|
|
if state.interrupted:
|
|
break
|
|
if not tiles[yi][xi]:
|
|
tiles[yi][xi] = not tiles[yi][xi]
|
|
continue
|
|
tiles[yi][xi] = not tiles[yi][xi]
|
|
draw.rectangle(self.calc_rectangle(xi, yi), fill="white")
|
|
p.init_images = [image]
|
|
p.image_mask = mask
|
|
processed = processing.process_images(p)
|
|
draw.rectangle(self.calc_rectangle(xi, yi), fill="black")
|
|
if (len(processed.images) > 0):
|
|
image = processed.images[0]
|
|
|
|
for yi in range(len(tiles)):
|
|
for xi in range(len(tiles[yi])):
|
|
if state.interrupted:
|
|
break
|
|
if not tiles[yi][xi]:
|
|
continue
|
|
draw.rectangle(self.calc_rectangle(xi, yi), fill="white")
|
|
p.init_images = [image]
|
|
p.image_mask = mask
|
|
processed = processing.process_images(p)
|
|
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, image, rows, cols):
|
|
self.initial_info = None
|
|
if self.mode == USDUMode.LINEAR:
|
|
return self.linear_process(p, image, rows, cols)
|
|
if self.mode == USDUMode.CHESS:
|
|
return self.chess_process(p, image, rows, cols)
|
|
|
|
class USDUSeamsFix():
|
|
|
|
def init_draw(self, p):
|
|
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, image, rows, cols):
|
|
|
|
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):
|
|
if state.interrupted:
|
|
break
|
|
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 = processing.process_images(p)
|
|
if (len(processed.images) > 0):
|
|
image = processed.images[0]
|
|
|
|
for yi in range(rows):
|
|
for xi in range(cols-1):
|
|
if state.interrupted:
|
|
break
|
|
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 = processing.process_images(p)
|
|
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 half_tile_process_corners(self, p, image, rows, cols):
|
|
fixed_image = self.half_tile_process(p, image, rows, cols)
|
|
processed = None
|
|
self.init_draw(p)
|
|
gradient = Image.radial_gradient("L").resize(
|
|
(self.tile_width, self.tile_height), resample=Image.BICUBIC)
|
|
gradient = ImageOps.invert(gradient)
|
|
p.denoising_strength = self.denoise
|
|
#p.mask_blur = 0
|
|
p.mask_blur = self.mask_blur
|
|
|
|
for yi in range(rows-1):
|
|
for xi in range(cols-1):
|
|
if state.interrupted:
|
|
break
|
|
p.width = self.tile_width
|
|
p.height = self.tile_height
|
|
p.inpaint_full_res = True
|
|
p.inpaint_full_res_padding = 0
|
|
mask = Image.new("L", (fixed_image.width, fixed_image.height), "black")
|
|
mask.paste(gradient, (xi*self.tile_width + self.tile_width//2,
|
|
yi*self.tile_height + self.tile_height//2))
|
|
|
|
p.init_images = [fixed_image]
|
|
p.image_mask = mask
|
|
processed = processing.process_images(p)
|
|
if (len(processed.images) > 0):
|
|
fixed_image = processed.images[0]
|
|
|
|
p.width = fixed_image.width
|
|
p.height = fixed_image.height
|
|
if processed is not None:
|
|
self.initial_info = processed.infotext(p, 0)
|
|
|
|
return fixed_image
|
|
|
|
def band_pass_process(self, p, image, cols, rows):
|
|
|
|
self.init_draw(p)
|
|
processed = None
|
|
|
|
p.denoising_strength = self.denoise
|
|
p.mask_blur = 0
|
|
|
|
gradient = Image.linear_gradient("L")
|
|
mirror_gradient = Image.new("L", (256, 256), "black")
|
|
mirror_gradient.paste(gradient.resize((256, 128), resample=Image.BICUBIC), (0, 0))
|
|
mirror_gradient.paste(gradient.rotate(180).resize((256, 128), resample=Image.BICUBIC), (0, 128))
|
|
|
|
row_gradient = mirror_gradient.resize((image.width, self.width), resample=Image.BICUBIC)
|
|
col_gradient = mirror_gradient.rotate(90).resize((self.width, image.height), resample=Image.BICUBIC)
|
|
|
|
for xi in range(1, rows):
|
|
if state.interrupted:
|
|
break
|
|
p.width = self.width + self.padding * 2
|
|
p.height = image.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.width // 2, 0))
|
|
|
|
p.init_images = [image]
|
|
p.image_mask = mask
|
|
processed = processing.process_images(p)
|
|
if (len(processed.images) > 0):
|
|
image = processed.images[0]
|
|
for yi in range(1, cols):
|
|
if state.interrupted:
|
|
break
|
|
p.width = image.width
|
|
p.height = self.width + self.padding * 2
|
|
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, (0, yi * self.tile_height - self.width // 2))
|
|
|
|
p.init_images = [image]
|
|
p.image_mask = mask
|
|
processed = processing.process_images(p)
|
|
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, image, rows, cols):
|
|
if USDUSFMode(self.mode) == USDUSFMode.BAND_PASS:
|
|
return self.band_pass_process(p, image, rows, cols)
|
|
elif USDUSFMode(self.mode) == USDUSFMode.HALF_TILE:
|
|
return self.half_tile_process(p, image, rows, cols)
|
|
elif USDUSFMode(self.mode) == USDUSFMode.HALF_TILE_PLUS_INTERSECTIONS:
|
|
return self.half_tile_process_corners(p, image, rows, cols)
|
|
else:
|
|
return image
|
|
|
|
class Script(scripts.Script):
|
|
def title(self):
|
|
return "Ultimate SD upscale"
|
|
|
|
def show(self, is_img2img):
|
|
return is_img2img
|
|
|
|
def ui(self, is_img2img):
|
|
|
|
target_size_types = [
|
|
"From img2img2 settings",
|
|
"Custom size",
|
|
"Scale from image size"
|
|
]
|
|
|
|
seams_fix_types = [
|
|
"None",
|
|
"Band pass",
|
|
"Half tile offset pass",
|
|
"Half tile offset pass + intersections"
|
|
]
|
|
|
|
redrow_modes = [
|
|
"Linear",
|
|
"Chess",
|
|
"None"
|
|
]
|
|
|
|
info = gr.HTML(
|
|
"<p style=\"margin-bottom:0.75em\">Will upscale the image depending on the selected target size type</p>")
|
|
|
|
with gr.Row():
|
|
target_size_type = gr.Dropdown(label="Target size type", choices=[k for k in target_size_types], type="index",
|
|
value=next(iter(target_size_types)))
|
|
|
|
custom_width = gr.Slider(label='Custom width', minimum=64, maximum=8192, step=64, value=2048, visible=False, interactive=True)
|
|
custom_height = gr.Slider(label='Custom height', minimum=64, maximum=8192, step=64, value=2048, visible=False, interactive=True)
|
|
custom_scale = gr.Slider(label='Scale', minimum=1, maximum=16, step=0.01, value=2, visible=False, interactive=True)
|
|
|
|
gr.HTML("<p style=\"margin-bottom:0.75em\">Redraw options:</p>")
|
|
with gr.Row():
|
|
upscaler_index = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers],
|
|
value=shared.sd_upscalers[0].name, type="index")
|
|
with gr.Row():
|
|
redraw_mode = gr.Dropdown(label="Type", choices=[k for k in redrow_modes], type="index", value=next(iter(redrow_modes)))
|
|
tile_width = gr.Slider(minimum=0, maximum=2048, step=64, label='Tile width', value=512)
|
|
tile_height = gr.Slider(minimum=0, maximum=2048, step=64, label='Tile height', value=0)
|
|
mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=8)
|
|
padding = gr.Slider(label='Padding', minimum=0, maximum=128, step=1, value=32)
|
|
gr.HTML("<p style=\"margin-bottom:0.75em\">Seams fix:</p>")
|
|
with gr.Row():
|
|
seams_fix_type = gr.Dropdown(label="Type", choices=[k for k in seams_fix_types], type="index", value=next(iter(seams_fix_types)))
|
|
seams_fix_denoise = gr.Slider(label='Denoise', minimum=0, maximum=1, step=0.01, value=0.35, visible=False, interactive=True)
|
|
seams_fix_width = gr.Slider(label='Width', minimum=0, maximum=128, step=1, value=64, visible=False, interactive=True)
|
|
seams_fix_mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4, visible=False, interactive=True)
|
|
seams_fix_padding = gr.Slider(label='Padding', minimum=0, maximum=128, step=1, value=16, visible=False, interactive=True)
|
|
gr.HTML("<p style=\"margin-bottom:0.75em\">Save options:</p>")
|
|
with gr.Row():
|
|
save_upscaled_image = gr.Checkbox(label="Upscaled", value=True)
|
|
save_seams_fix_image = gr.Checkbox(label="Seams fix", value=False)
|
|
|
|
def select_fix_type(fix_index):
|
|
all_visible = fix_index != 0
|
|
mask_blur_visible = fix_index == 2 or fix_index == 3
|
|
width_visible = fix_index == 1
|
|
|
|
return [gr.update(visible=all_visible),
|
|
gr.update(visible=width_visible),
|
|
gr.update(visible=mask_blur_visible),
|
|
gr.update(visible=all_visible)]
|
|
|
|
seams_fix_type.change(
|
|
fn=select_fix_type,
|
|
inputs=seams_fix_type,
|
|
outputs=[seams_fix_denoise, seams_fix_width, seams_fix_mask_blur, seams_fix_padding]
|
|
)
|
|
|
|
def select_scale_type(scale_index):
|
|
is_custom_size = scale_index == 1
|
|
is_custom_scale = scale_index == 2
|
|
|
|
return [gr.update(visible=is_custom_size),
|
|
gr.update(visible=is_custom_size),
|
|
gr.update(visible=is_custom_scale),
|
|
]
|
|
|
|
target_size_type.change(
|
|
fn=select_scale_type,
|
|
inputs=target_size_type,
|
|
outputs=[custom_width, custom_height, custom_scale]
|
|
)
|
|
|
|
return [info, tile_width, tile_height, mask_blur, padding, seams_fix_width, seams_fix_denoise, seams_fix_padding,
|
|
upscaler_index, save_upscaled_image, redraw_mode, save_seams_fix_image, seams_fix_mask_blur,
|
|
seams_fix_type, target_size_type, custom_width, custom_height, custom_scale]
|
|
|
|
def run(self, p, _, tile_width, tile_height, mask_blur, padding, seams_fix_width, seams_fix_denoise, seams_fix_padding,
|
|
upscaler_index, save_upscaled_image, redraw_mode, save_seams_fix_image, seams_fix_mask_blur,
|
|
seams_fix_type, target_size_type, custom_width, custom_height, custom_scale):
|
|
|
|
# Init
|
|
processing.fix_seed(p)
|
|
devices.torch_gc()
|
|
|
|
p.do_not_save_grid = True
|
|
p.do_not_save_samples = True
|
|
p.inpaint_full_res = False
|
|
|
|
p.inpainting_fill = 1
|
|
|
|
seed = p.seed
|
|
|
|
# Init image
|
|
init_img = p.init_images[0]
|
|
if init_img == None:
|
|
return Processed(p, [], seed, "Empty image")
|
|
init_img = images.flatten(init_img, opts.img2img_background_color)
|
|
|
|
#override size
|
|
if target_size_type == 1:
|
|
p.width = custom_width
|
|
p.height = custom_height
|
|
if target_size_type == 2:
|
|
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()
|
|
result_images = upscaler.result_images
|
|
|
|
return Processed(p, result_images, seed, upscaler.initial_info if upscaler.initial_info is not None else "")
|
|
|