This commit is contained in:
Haoming 2026-03-17 14:40:39 +08:00
parent a32b497149
commit 43b79cd349
2 changed files with 137 additions and 124 deletions

View File

@ -55,8 +55,8 @@ def image_grid(imgs, batch_size=1, rows=None):
script_callbacks.image_grid_callback(params)
w, h = map(max, zip(*(img.size for img in imgs)))
grid_background_color = ImageColor.getcolor(opts.grid_background_color, 'RGBA')
grid = Image.new('RGBA', size=(params.cols * w, params.rows * h), color=grid_background_color)
grid_background_color = ImageColor.getcolor(opts.grid_background_color, "RGBA")
grid = Image.new("RGBA", size=(params.cols * w, params.rows * h), color=grid_background_color)
for i, img in enumerate(params.imgs):
img_w, img_h = img.size
@ -115,7 +115,7 @@ def combine_grid(grid):
def make_mask_image(r):
r = r * 255 / grid.overlap
r = r.astype(np.uint8)
return Image.fromarray(r, 'L')
return Image.fromarray(r, "L")
mask_w = make_mask_image(np.arange(grid.overlap, dtype=np.float32).reshape((1, grid.overlap)).repeat(grid.tile_h, axis=0))
mask_h = make_mask_image(np.arange(grid.overlap, dtype=np.float32).reshape((grid.overlap, 1)).repeat(grid.image_w, axis=1))
@ -142,7 +142,7 @@ def combine_grid(grid):
class GridAnnotation:
def __init__(self, text='', is_active=True):
def __init__(self, text="", is_active=True):
self.text = text
self.is_active = is_active
self.size = None
@ -150,14 +150,14 @@ class GridAnnotation:
def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
color_active = ImageColor.getcolor(opts.grid_text_active_color, 'RGB')
color_inactive = ImageColor.getcolor(opts.grid_text_inactive_color, 'RGB')
color_background = ImageColor.getcolor(opts.grid_background_color, 'RGB')
color_active = ImageColor.getcolor(opts.grid_text_active_color, "RGB")
color_inactive = ImageColor.getcolor(opts.grid_text_inactive_color, "RGB")
color_background = ImageColor.getcolor(opts.grid_background_color, "RGB")
def wrap(drawing, text, font, line_length):
lines = ['']
lines = [""]
for word in text.split():
line = f'{lines[-1]} {word}'.strip()
line = f"{lines[-1]} {word}".strip()
if drawing.textlength(line, font=font) <= line_length:
lines[-1] = line
else:
@ -192,8 +192,8 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
cols = im.width // width
rows = im.height // height
assert cols == len(hor_texts), f'bad number of horizontal texts: {len(hor_texts)}; must be {cols}'
assert rows == len(ver_texts), f'bad number of vertical texts: {len(ver_texts)}; must be {rows}'
assert cols == len(hor_texts), f"bad number of horizontal texts: {len(hor_texts)}; must be {cols}"
assert rows == len(ver_texts), f"bad number of vertical texts: {len(ver_texts)}; must be {rows}"
calc_img = Image.new("RGB", (1, 1), color_background)
calc_d = ImageDraw.Draw(calc_img)
@ -216,11 +216,11 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
pad_top = 0 if sum(hor_text_heights) == 0 else max(hor_text_heights) + line_spacing * 2
result = Image.new("RGB", (im.width + pad_left + margin * (cols-1), im.height + pad_top + margin * (rows-1)), color_background)
result = Image.new("RGB", (im.width + pad_left + margin * (cols - 1), im.height + pad_top + margin * (rows - 1)), color_background)
for row in range(rows):
for col in range(cols):
cell = im.crop((width * col, height * row, width * (col+1), height * (row+1)))
cell = im.crop((width * col, height * row, width * (col + 1), height * (row + 1)))
result.paste(cell, (pad_left + (width + margin) * col, pad_top + (height + margin) * row))
d = ImageDraw.Draw(result)
@ -268,13 +268,13 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, force_RGBA=
upscaler_name: The name of the upscaler to use. If not provided, defaults to opts.upscaler_for_img2img.
"""
if not force_RGBA and im.mode == 'RGBA':
im = im.convert('RGB')
if not force_RGBA and im.mode == "RGBA":
im = im.convert("RGB")
upscaler_name = upscaler_name or opts.upscaler_for_img2img
def resize(im, w, h):
if upscaler_name is None or upscaler_name == "None" or im.mode == 'L' or force_RGBA:
if upscaler_name is None or upscaler_name == "None" or im.mode == "L" or force_RGBA:
return im.resize((w, h), resample=LANCZOS)
scale = max(w / im.width, h / im.height)
@ -336,10 +336,10 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, force_RGBA=
if not shared.cmd_opts.unix_filenames_sanitization:
invalid_filename_chars = '#<>:"/\\|?*\n\r\t'
else:
invalid_filename_chars = '/'
invalid_filename_prefix = ' '
invalid_filename_postfix = ' .'
re_nonletters = re.compile(r'[\s' + string.punctuation + ']+')
invalid_filename_chars = "/"
invalid_filename_prefix = " "
invalid_filename_postfix = " ."
re_nonletters = re.compile(r"[\s" + string.punctuation + "]+")
re_pattern = re.compile(r"(.*?)(?:\[([^\[\]]+)\]|$)")
re_pattern_arg = re.compile(r"(.*)<([^>]*)>$")
max_filename_part_length = shared.cmd_opts.filenames_max_length
@ -351,9 +351,9 @@ def sanitize_filename_part(text, replace_spaces=True):
return None
if replace_spaces:
text = text.replace(' ', '_')
text = text.replace(" ", "_")
text = text.translate({ord(x): '_' for x in invalid_filename_chars})
text = text.translate({ord(x): "_" for x in invalid_filename_chars})
text = text.lstrip(invalid_filename_prefix)[:max_filename_part_length]
text = text.rstrip(invalid_filename_postfix)
return text
@ -362,21 +362,21 @@ def sanitize_filename_part(text, replace_spaces=True):
@functools.cache
def get_scheduler_str(sampler_name, scheduler_name):
"""Returns {Scheduler} if the scheduler is applicable to the sampler"""
if scheduler_name == 'Automatic':
if scheduler_name == "Automatic":
config = sd_samplers.find_sampler_config(sampler_name)
scheduler_name = config.options.get('scheduler', 'Automatic')
scheduler_name = config.options.get("scheduler", "Automatic")
return scheduler_name.capitalize()
@functools.cache
def get_sampler_scheduler_str(sampler_name, scheduler_name):
"""Returns the '{Sampler} {Scheduler}' if the scheduler is applicable to the sampler"""
return f'{sampler_name} {get_scheduler_str(sampler_name, scheduler_name)}'
return f"{sampler_name} {get_scheduler_str(sampler_name, scheduler_name)}"
def get_sampler_scheduler(p, sampler):
"""Returns '{Sampler} {Scheduler}' / '{Scheduler}' / 'NOTHING_AND_SKIP_PREVIOUS_TEXT'"""
if hasattr(p, 'scheduler') and hasattr(p, 'sampler_name'):
if hasattr(p, "scheduler") and hasattr(p, "sampler_name"):
if sampler:
sampler_scheduler = get_sampler_scheduler_str(p.sampler_name, p.scheduler)
else:
@ -387,42 +387,42 @@ def get_sampler_scheduler(p, sampler):
class FilenameGenerator:
replacements = {
'basename': lambda self: self.basename or 'img',
'seed': lambda self: self.seed if self.seed is not None else '',
'seed_first': lambda self: self.seed if self.p.batch_size == 1 else self.p.all_seeds[0],
'seed_last': lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.batch_size == 1 else self.p.all_seeds[-1],
'steps': lambda self: self.p and self.p.steps,
'cfg': lambda self: self.p and self.p.cfg_scale,
'width': lambda self: self.image.width,
'height': lambda self: self.image.height,
'styles': lambda self: self.p and sanitize_filename_part(", ".join([style for style in self.p.styles if not style == "None"]) or "None", replace_spaces=False),
'sampler': lambda self: self.p and sanitize_filename_part(self.p.sampler_name, replace_spaces=False),
'sampler_scheduler': lambda self: self.p and get_sampler_scheduler(self.p, True),
'scheduler': lambda self: self.p and get_sampler_scheduler(self.p, False),
'model_hash': lambda self: getattr(self.p, "sd_model_hash", shared.sd_model.sd_model_hash),
'model_name': lambda self: sanitize_filename_part(shared.sd_model.sd_checkpoint_info.name_for_extra, replace_spaces=False),
'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
'datetime': lambda self, *args: self.datetime(*args), # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
'job_timestamp': lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
'prompt_hash': lambda self, *args: self.string_hash(self.prompt, *args),
'negative_prompt_hash': lambda self, *args: self.string_hash(self.p.negative_prompt, *args),
'full_prompt_hash': lambda self, *args: self.string_hash(f"{self.p.prompt} {self.p.negative_prompt}", *args), # a space in between to create a unique string
'prompt': lambda self: sanitize_filename_part(self.prompt),
'prompt_no_styles': lambda self: self.prompt_no_style(),
'prompt_spaces': lambda self: sanitize_filename_part(self.prompt, replace_spaces=False),
'prompt_words': lambda self: self.prompt_words(),
'batch_number': lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.batch_size == 1 or self.zip else self.p.batch_index + 1,
'batch_size': lambda self: self.p.batch_size,
'generation_number': lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if (self.p.n_iter == 1 and self.p.batch_size == 1) or self.zip else self.p.iteration * self.p.batch_size + self.p.batch_index + 1,
'hasprompt': lambda self, *args: self.hasprompt(*args), # accepts formats:[hasprompt<prompt1|default><prompt2>..]
'clip_skip': lambda self: opts.data["CLIP_stop_at_last_layers"],
'denoising': lambda self: self.p.denoising_strength if self.p and self.p.denoising_strength else NOTHING_AND_SKIP_PREVIOUS_TEXT,
'user': lambda self: self.p.user,
'vae_filename': lambda self: self.get_vae_filename(),
'none': lambda self: '', # Overrides the default, so you can get just the sequence number
'image_hash': lambda self, *args: self.image_hash(*args) # accepts formats: [image_hash<length>] default full hash
"basename": lambda self: self.basename or "img",
"seed": lambda self: self.seed if self.seed is not None else "",
"seed_first": lambda self: self.seed if self.p.batch_size == 1 else self.p.all_seeds[0],
"seed_last": lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.batch_size == 1 else self.p.all_seeds[-1],
"steps": lambda self: self.p and self.p.steps,
"cfg": lambda self: self.p and self.p.cfg_scale,
"width": lambda self: self.image.width,
"height": lambda self: self.image.height,
"styles": lambda self: self.p and sanitize_filename_part(", ".join([style for style in self.p.styles if not style == "None"]) or "None", replace_spaces=False),
"sampler": lambda self: self.p and sanitize_filename_part(self.p.sampler_name, replace_spaces=False),
"sampler_scheduler": lambda self: self.p and get_sampler_scheduler(self.p, True),
"scheduler": lambda self: self.p and get_sampler_scheduler(self.p, False),
"model_hash": lambda self: getattr(self.p, "sd_model_hash", shared.sd_model.sd_model_hash),
"model_name": lambda self: sanitize_filename_part(shared.sd_model.sd_checkpoint_info.name_for_extra, replace_spaces=False),
"date": lambda self: datetime.datetime.now().strftime("%Y-%m-%d"),
"datetime": lambda self, *args: self.datetime(*args), # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
"job_timestamp": lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
"prompt_hash": lambda self, *args: self.string_hash(self.prompt, *args),
"negative_prompt_hash": lambda self, *args: self.string_hash(self.p.negative_prompt, *args),
"full_prompt_hash": lambda self, *args: self.string_hash(f"{self.p.prompt} {self.p.negative_prompt}", *args), # a space in between to create a unique string
"prompt": lambda self: sanitize_filename_part(self.prompt),
"prompt_no_styles": lambda self: self.prompt_no_style(),
"prompt_spaces": lambda self: sanitize_filename_part(self.prompt, replace_spaces=False),
"prompt_words": lambda self: self.prompt_words(),
"batch_number": lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if self.p.batch_size == 1 or self.zip else self.p.batch_index + 1,
"batch_size": lambda self: self.p.batch_size,
"generation_number": lambda self: NOTHING_AND_SKIP_PREVIOUS_TEXT if (self.p.n_iter == 1 and self.p.batch_size == 1) or self.zip else self.p.iteration * self.p.batch_size + self.p.batch_index + 1,
"hasprompt": lambda self, *args: self.hasprompt(*args), # accepts formats:[hasprompt<prompt1|default><prompt2>..]
"clip_skip": lambda self: opts.data["CLIP_stop_at_last_layers"],
"denoising": lambda self: self.p.denoising_strength if self.p and self.p.denoising_strength else NOTHING_AND_SKIP_PREVIOUS_TEXT,
"user": lambda self: self.p.user,
"vae_filename": lambda self: self.get_vae_filename(),
"none": lambda self: "", # Overrides the default, so you can get just the sequence number
"image_hash": lambda self, *args: self.image_hash(*args), # accepts formats: [image_hash<length>] default full hash
}
default_time_format = '%Y%m%d%H%M%S'
default_time_format = "%Y%m%d%H%M%S"
def __init__(self, p, seed, prompt, image, zip=False, basename=""):
self.p = p
@ -441,13 +441,12 @@ class FilenameGenerator:
return "NoneType"
file_name = os.path.basename(sd_vae.loaded_vae_file)
split_file_name = file_name.split('.')
if len(split_file_name) > 1 and split_file_name[0] == '':
split_file_name = file_name.split(".")
if len(split_file_name) > 1 and split_file_name[0] == "":
return split_file_name[1] # if the first character of the filename is "." then [1] is obtained.
else:
return split_file_name[0]
def hasprompt(self, *args):
lower = self.prompt.lower()
if self.p is None or self.prompt is None:
@ -459,9 +458,9 @@ class FilenameGenerator:
expected = division[0].lower()
default = division[1] if len(division) > 1 else ""
if lower.find(expected) >= 0:
outres = f'{outres}{expected}'
outres = f"{outres}{expected}"
else:
outres = outres if default == "" else f'{outres}{default}'
outres = outres if default == "" else f"{outres}{default}"
return sanitize_filename_part(outres)
def prompt_no_style(self):
@ -472,9 +471,9 @@ class FilenameGenerator:
for style in shared.prompt_styles.get_style_prompts(self.p.styles):
if style:
for part in style.split("{prompt}"):
prompt_no_style = prompt_no_style.replace(part, "").replace(", ,", ",").strip().strip(',')
prompt_no_style = prompt_no_style.replace(part, "").replace(", ,", ",").strip().strip(",")
prompt_no_style = prompt_no_style.replace(style, "").strip().strip(',').strip()
prompt_no_style = prompt_no_style.replace(style, "").strip().strip(",").strip()
return sanitize_filename_part(prompt_no_style, replace_spaces=False)
@ -482,7 +481,7 @@ class FilenameGenerator:
words = [x for x in re_nonletters.split(self.prompt or "") if x]
if len(words) == 0:
words = ["empty"]
return sanitize_filename_part(" ".join(words[0:opts.directories_max_prompt_words]), replace_spaces=False)
return sanitize_filename_part(" ".join(words[0 : opts.directories_max_prompt_words]), replace_spaces=False)
def datetime(self, *args):
time_datetime = datetime.datetime.now()
@ -510,7 +509,7 @@ class FilenameGenerator:
return hashlib.sha256(text.encode()).hexdigest()[0:length]
def apply(self, x):
res = ''
res = ""
for m in re_pattern.finditer(x):
text, pattern = m.groups()
@ -542,7 +541,7 @@ class FilenameGenerator:
res += text + str(replacement)
continue
res += f'{text}[{pattern}]'
res += f"{text}[{pattern}]"
return res
@ -554,13 +553,13 @@ def get_next_sequence_number(path, basename):
The sequence starts at 0.
"""
result = -1
if basename != '':
if basename != "":
basename = f"{basename}-"
prefix_length = len(basename)
for p in os.listdir(path):
if p.startswith(basename):
parts = os.path.splitext(p[prefix_length:])[0].split('-') # splits the filename (removing the basename first if one is defined, so the sequence number is always the first element)
parts = os.path.splitext(p[prefix_length:])[0].split("-") # splits the filename (removing the basename first if one is defined, so the sequence number is always the first element)
try:
result = max(int(parts[0]), result)
except ValueError:
@ -626,7 +625,7 @@ def save_image_with_geninfo(image, geninfo, filename, extension=None, existing_p
image.save(filename, format=image_format, quality=opts.jpeg_quality)
def save_image(image, path, basename, seed=None, prompt=None, extension='png', info=None, short_filename=False, no_prompt=False, grid=False, pnginfo_section_name='parameters', p=None, existing_info=None, forced_filename=None, suffix="", save_to_dirs=None):
def save_image(image, path, basename, seed=None, prompt=None, extension="png", info=None, short_filename=False, no_prompt=False, grid=False, pnginfo_section_name="parameters", p=None, existing_info=None, forced_filename=None, suffix="", save_to_dirs=None):
"""Save an image.
Args:
@ -663,14 +662,14 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
# WebP and JPG formats have maximum dimension limits of 16383 and 65535 respectively. switch to PNG which has a much higher limit
if (image.height > 65535 or image.width > 65535) and extension.lower() in ("jpg", "jpeg") or (image.height > 16383 or image.width > 16383) and extension.lower() == "webp":
print('Image dimensions too large; saving as PNG')
print("Image dimensions too large; saving as PNG")
extension = "png"
if save_to_dirs is None:
save_to_dirs = (grid and opts.grid_save_to_dirs) or (not grid and opts.save_to_dirs and not no_prompt)
if save_to_dirs:
dirname = namegen.apply(opts.directories_filename_pattern or "[prompt_words]").lstrip(' ').rstrip('\\ /')
dirname = namegen.apply(opts.directories_filename_pattern or "[prompt_words]").lstrip(" ").rstrip("\\ /")
path = os.path.join(path, dirname)
os.makedirs(path, exist_ok=True)
@ -678,7 +677,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
if forced_filename is None:
if short_filename or seed is None:
file_decoration = ""
elif hasattr(p, 'override_settings'):
elif hasattr(p, "override_settings"):
file_decoration = p.override_settings.get("samples_filename_pattern")
else:
file_decoration = None
@ -688,7 +687,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
file_decoration = namegen.apply(file_decoration) + suffix
add_number = opts.save_images_add_number or file_decoration == ''
add_number = opts.save_images_add_number or file_decoration == ""
if file_decoration != "" and add_number:
file_decoration = f"-{file_decoration}"
@ -697,7 +696,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
basecount = get_next_sequence_number(path, basename)
fullfn = None
for i in range(500):
fn = f"{basecount + i:05}" if basename == '' else f"{basename}-{basecount + i:04}"
fn = f"{basecount + i:05}" if basename == "" else f"{basename}-{basecount + i:04}"
fullfn = os.path.join(path, f"{fn}{file_decoration}.{extension}")
if not os.path.exists(fullfn):
break
@ -737,9 +736,9 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
return without_extension
fullfn_without_extension, extension = os.path.splitext(params.filename)
if hasattr(os, 'statvfs'):
if hasattr(os, "statvfs"):
max_name_len = os.statvfs(path).f_namemax
fullfn_without_extension = fullfn_without_extension[:max_name_len - max(4, len(extension))]
fullfn_without_extension = fullfn_without_extension[: max_name_len - max(4, len(extension))]
params.filename = fullfn_without_extension + extension
fullfn = params.filename
@ -780,9 +779,21 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i
IGNORED_INFO_KEYS = {
'jfif', 'jfif_version', 'jfif_unit', 'jfif_density', 'dpi', 'exif',
'loop', 'background', 'timestamp', 'duration', 'progressive', 'progression',
'icc_profile', 'chromaticity', 'photoshop',
"jfif",
"jfif_version",
"jfif_unit",
"jfif_density",
"dpi",
"exif",
"loop",
"background",
"timestamp",
"duration",
"progressive",
"progression",
"icc_profile",
"chromaticity",
"photoshop",
}
@ -792,7 +803,7 @@ def read_info_from_image(image: Image.Image) -> tuple[str | None, dict]:
def read_standard():
items = (image.info or {}).copy()
geninfo = items.pop('parameters', None)
geninfo = items.pop("parameters", None)
if "exif" in items:
exif_data = items["exif"]
@ -801,17 +812,17 @@ def read_info_from_image(image: Image.Image) -> tuple[str | None, dict]:
except OSError:
# memory / exif was not valid so piexif tried to read from a file
exif = None
exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b'')
exif_comment = (exif or {}).get("Exif", {}).get(piexif.ExifIFD.UserComment, b"")
try:
exif_comment = piexif.helper.UserComment.load(exif_comment)
except ValueError:
exif_comment = exif_comment.decode('utf8', errors="ignore")
exif_comment = exif_comment.decode("utf8", errors="ignore")
if exif_comment:
geninfo = exif_comment
elif "comment" in items: # for gif
elif "comment" in items: # for gif
if isinstance(items["comment"], bytes):
geninfo = items["comment"].decode('utf8', errors="ignore")
geninfo = items["comment"].decode("utf8", errors="ignore")
else:
geninfo = items["comment"]
@ -847,7 +858,7 @@ def image_data(data):
pass
try:
text = data.decode('utf8')
text = data.decode("utf8")
assert len(text) < 10000
return text, None
@ -861,11 +872,11 @@ def flatten(img, bgcolor):
"""replaces transparency with bgcolor (example: "#ffffff"), returning an RGB mode image with no transparency"""
if img.mode == "RGBA":
background = Image.new('RGBA', img.size, bgcolor)
background = Image.new("RGBA", img.size, bgcolor)
background.paste(img, mask=img)
img = background
return img.convert('RGB')
return img.convert("RGB")
def read(fp, **kwargs):

View File

@ -21,28 +21,28 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
for img in image_folder:
if isinstance(img, Image.Image):
image = images.fix_image(img)
fn = ''
fn = ""
else:
image = images.read(os.path.abspath(img.name))
fn = os.path.splitext(img.name)[0]
yield image, fn
elif extras_mode == 2:
assert not shared.cmd_opts.hide_ui_dir_config, '--hide-ui-dir-config option must be disabled'
assert input_dir, 'input directory not selected'
assert not shared.cmd_opts.hide_ui_dir_config, "--hide-ui-dir-config option must be disabled"
assert input_dir, "input directory not selected"
image_list = shared.listfiles(input_dir)
for filename in image_list:
yield filename, filename
else:
assert image, 'image not selected'
assert image, "image not selected"
yield image, None
if extras_mode == 2 and output_dir != '':
if extras_mode == 2 and output_dir != "":
outpath = output_dir
else:
outpath = opts.outdir_samples or opts.outdir_extras_samples
infotext = ''
infotext = ""
data_to_process = list(get_images(extras_mode, image, image_folder, input_dir))
shared.state.job_count = len(data_to_process)
@ -86,10 +86,10 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
basename = os.path.splitext(os.path.basename(name))[0]
forced_filename = basename + suffix
else:
basename = ''
basename = ""
forced_filename = None
infotext = ", ".join([k if k == v else f'{k}: {infotext_utils.quote(v)}' for k, v in pp.info.items() if v is not None])
infotext = ", ".join([k if k == v else f"{k}: {infotext_utils.quote(v)}" for k, v in pp.info.items() if v is not None])
if opts.enable_pnginfo:
pp.image.info = existing_pnginfo
@ -104,7 +104,7 @@ def run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir,
devices.torch_gc()
shared.state.end()
return outputs, ui_common.plaintext_to_html(infotext), ''
return outputs, ui_common.plaintext_to_html(infotext), ""
def run_postprocessing_webui(id_task, *args, **kwargs):
@ -114,28 +114,30 @@ def run_postprocessing_webui(id_task, *args, **kwargs):
def run_extras(extras_mode, resize_mode, image, image_folder, input_dir, output_dir, show_extras_results, gfpgan_visibility, codeformer_visibility, codeformer_weight, upscaling_resize, upscaling_resize_w, upscaling_resize_h, upscaling_crop, extras_upscaler_1, extras_upscaler_2, extras_upscaler_2_visibility, upscale_first: bool, save_output: bool = True, max_side_length: int = 0):
"""old handler for API"""
args = scripts.scripts_postproc.create_args_for_run({
"Upscale": {
"upscale_enabled": True,
"upscale_mode": resize_mode,
"upscale_by": upscaling_resize,
"max_side_length": max_side_length,
"upscale_to_width": upscaling_resize_w,
"upscale_to_height": upscaling_resize_h,
"upscale_crop": upscaling_crop,
"upscaler_1_name": extras_upscaler_1,
"upscaler_2_name": extras_upscaler_2,
"upscaler_2_visibility": extras_upscaler_2_visibility,
},
"GFPGAN": {
"enable": True,
"gfpgan_visibility": gfpgan_visibility,
},
"CodeFormer": {
"enable": True,
"codeformer_visibility": codeformer_visibility,
"codeformer_weight": codeformer_weight,
},
})
args = scripts.scripts_postproc.create_args_for_run(
{
"Upscale": {
"upscale_enabled": True,
"upscale_mode": resize_mode,
"upscale_by": upscaling_resize,
"max_side_length": max_side_length,
"upscale_to_width": upscaling_resize_w,
"upscale_to_height": upscaling_resize_h,
"upscale_crop": upscaling_crop,
"upscaler_1_name": extras_upscaler_1,
"upscaler_2_name": extras_upscaler_2,
"upscaler_2_visibility": extras_upscaler_2_visibility,
},
"GFPGAN": {
"enable": True,
"gfpgan_visibility": gfpgan_visibility,
},
"CodeFormer": {
"enable": True,
"codeformer_visibility": codeformer_visibility,
"codeformer_weight": codeformer_weight,
},
}
)
return run_postprocessing(extras_mode, image, image_folder, input_dir, output_dir, show_extras_results, *args, save_output=save_output)