From 03ee67bfd34b9e872b33eb05fef5db83410b16f3 Mon Sep 17 00:00:00 2001 From: WDevelopsWebApps <97454358+WDevelopsWebApps@users.noreply.github.com> Date: Wed, 28 Sep 2022 10:53:40 +0200 Subject: add advanced saving for save button --- modules/images.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index 9458bf8d..923f81df 100644 --- a/modules/images.py +++ b/modules/images.py @@ -290,7 +290,10 @@ def apply_filename_pattern(x, p, seed, prompt): x = x.replace("[cfg]", str(p.cfg_scale)) x = x.replace("[width]", str(p.width)) x = x.replace("[height]", str(p.height)) - x = x.replace("[styles]", sanitize_filename_part(", ".join(p.styles), replace_spaces=False)) + #currently disabled if using the save button, will work otherwise + # if enabled it will cause a bug because styles is not included in the save_files data dictionary + if hasattr(p, "styles"): + x = x.replace("[styles]", sanitize_filename_part(", ".join(p.styles), replace_spaces=False)) x = x.replace("[sampler]", sanitize_filename_part(sd_samplers.samplers[p.sampler_index].name, replace_spaces=False)) x = x.replace("[model_hash]", shared.sd_model.sd_model_hash) -- cgit v1.2.3 From 980cd1697ae980f57399da2b90462c07d102d935 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Fri, 30 Sep 2022 14:23:41 +0300 Subject: prevent neural network resizing when it is not necessary #1109 --- modules/images.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index 2e8305ed..8f34dcc1 100644 --- a/modules/images.py +++ b/modules/images.py @@ -213,17 +213,19 @@ def resize_image(resize_mode, im, width, height): if opts.upscaler_for_img2img is None or opts.upscaler_for_img2img == "None" or im.mode == 'L': return im.resize((w, h), resample=LANCZOS) - upscalers = [x for x in shared.sd_upscalers if x.name == opts.upscaler_for_img2img] - assert len(upscalers) > 0, f"could not find upscaler named {opts.upscaler_for_img2img}" - - upscaler = upscalers[0] scale = max(w / im.width, h / im.height) - upscaled = upscaler.scaler.upscale(im, scale, upscaler.data_path) - if upscaled.width != w or upscaled.height != h: - upscaled = im.resize((w, h), resample=LANCZOS) + if scale > 1.0: + upscalers = [x for x in shared.sd_upscalers if x.name == opts.upscaler_for_img2img] + assert len(upscalers) > 0, f"could not find upscaler named {opts.upscaler_for_img2img}" + + upscaler = upscalers[0] + im = upscaler.scaler.upscale(im, scale, upscaler.data_path) + + if im.width != w or im.height != h: + im = im.resize((w, h), resample=LANCZOS) - return upscaled + return im if resize_mode == 0: res = resize(im, width, height) -- cgit v1.2.3 From 3cf1a96006daffedb8ecd0ae142eca4c4da06105 Mon Sep 17 00:00:00 2001 From: RnDMonkey Date: Sat, 1 Oct 2022 21:11:03 -0700 Subject: added safety for blank directory naming patterns --- modules/images.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index f1aed5d6..e7894b4c 100644 --- a/modules/images.py +++ b/modules/images.py @@ -311,7 +311,7 @@ def apply_filename_pattern(x, p, seed, prompt): x = x.replace("[cfg]", str(p.cfg_scale)) x = x.replace("[width]", str(p.width)) x = x.replace("[height]", str(p.height)) - x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"]), replace_spaces=False)) + x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"]) or "No styles", replace_spaces=False)) x = x.replace("[sampler]", sanitize_filename_part(sd_samplers.samplers[p.sampler_index].name, replace_spaces=False)) x = x.replace("[model_hash]", shared.sd_model.sd_model_hash) @@ -374,7 +374,7 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i 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 = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt) + dirname = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt).strip('\\ ') path = os.path.join(path, dirname) os.makedirs(path, exist_ok=True) -- cgit v1.2.3 From 70f526704721a303ae045f6406439dcceee4302e Mon Sep 17 00:00:00 2001 From: RnDMonkey Date: Sat, 1 Oct 2022 21:18:15 -0700 Subject: use os.path.normpath for better safety checking --- modules/images.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index e7894b4c..5ef7eb92 100644 --- a/modules/images.py +++ b/modules/images.py @@ -374,8 +374,8 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i 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 = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt).strip('\\ ') - path = os.path.join(path, dirname) + dirname = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt) + path = os.path.normpath(os.path.join(path, dirname)) os.makedirs(path, exist_ok=True) -- cgit v1.2.3 From 32edf1732f27a1fad5133667c22b948adda1b070 Mon Sep 17 00:00:00 2001 From: RnDMonkey Date: Sat, 1 Oct 2022 21:37:14 -0700 Subject: os.path.normpath wasn't working, reverting to manual strip --- modules/images.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index 5ef7eb92..4998e92c 100644 --- a/modules/images.py +++ b/modules/images.py @@ -374,8 +374,8 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i 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 = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt) - path = os.path.normpath(os.path.join(path, dirname)) + dirname = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt).strip('\\ /') + path = os.path.join(path, dirname) os.makedirs(path, exist_ok=True) -- cgit v1.2.3 From 36ea4ac0f5844e5c8dec124edbdb714ccdd6013c Mon Sep 17 00:00:00 2001 From: RnDMonkey Date: Sun, 2 Oct 2022 22:21:16 -0700 Subject: moved no-style return outside join function --- modules/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index bba55158..1a046aca 100644 --- a/modules/images.py +++ b/modules/images.py @@ -315,7 +315,7 @@ def apply_filename_pattern(x, p, seed, prompt): #currently disabled if using the save button, will work otherwise # if enabled it will cause a bug because styles is not included in the save_files data dictionary if hasattr(p, "styles"): - x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"] or "None"), replace_spaces=False)) + x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"]) or "None", replace_spaces=False)) x = x.replace("[sampler]", sanitize_filename_part(sd_samplers.samplers[p.sampler_index].name, replace_spaces=False)) -- cgit v1.2.3 From eec1b39bd54711ca31e43022d2d6ac8c6d7281da Mon Sep 17 00:00:00 2001 From: Milly Date: Tue, 4 Oct 2022 20:16:52 +0900 Subject: Apply prompt pattern last --- modules/images.py | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index bba55158..5b56c7e3 100644 --- a/modules/images.py +++ b/modules/images.py @@ -287,6 +287,25 @@ def apply_filename_pattern(x, p, seed, prompt): if seed is not None: x = x.replace("[seed]", str(seed)) + if p is not None: + x = x.replace("[steps]", str(p.steps)) + x = x.replace("[cfg]", str(p.cfg_scale)) + x = x.replace("[width]", str(p.width)) + x = x.replace("[height]", str(p.height)) + + #currently disabled if using the save button, will work otherwise + # if enabled it will cause a bug because styles is not included in the save_files data dictionary + if hasattr(p, "styles"): + x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"] or "None"), replace_spaces=False)) + + x = x.replace("[sampler]", sanitize_filename_part(sd_samplers.samplers[p.sampler_index].name, replace_spaces=False)) + + x = x.replace("[model_hash]", shared.sd_model.sd_model_hash) + x = x.replace("[date]", datetime.date.today().isoformat()) + x = x.replace("[datetime]", datetime.datetime.now().strftime("%Y%m%d%H%M%S")) + x = x.replace("[job_timestamp]", shared.state.job_timestamp) + + # Apply [prompt] at last. Because it may contain any replacement word.^M if prompt is not None: x = x.replace("[prompt]", sanitize_filename_part(prompt)) if "[prompt_no_styles]" in x: @@ -295,7 +314,7 @@ def apply_filename_pattern(x, p, seed, prompt): if len(style) > 0: style_parts = [y for y in style.split("{prompt}")] for part in style_parts: - 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() x = x.replace("[prompt_no_styles]", sanitize_filename_part(prompt_no_style, replace_spaces=False)) @@ -306,24 +325,6 @@ def apply_filename_pattern(x, p, seed, prompt): words = ["empty"] x = x.replace("[prompt_words]", sanitize_filename_part(" ".join(words[0:max_prompt_words]), replace_spaces=False)) - if p is not None: - x = x.replace("[steps]", str(p.steps)) - x = x.replace("[cfg]", str(p.cfg_scale)) - x = x.replace("[width]", str(p.width)) - x = x.replace("[height]", str(p.height)) - - #currently disabled if using the save button, will work otherwise - # if enabled it will cause a bug because styles is not included in the save_files data dictionary - if hasattr(p, "styles"): - x = x.replace("[styles]", sanitize_filename_part(", ".join([x for x in p.styles if not x == "None"] or "None"), replace_spaces=False)) - - x = x.replace("[sampler]", sanitize_filename_part(sd_samplers.samplers[p.sampler_index].name, replace_spaces=False)) - - x = x.replace("[model_hash]", shared.sd_model.sd_model_hash) - x = x.replace("[date]", datetime.date.today().isoformat()) - x = x.replace("[datetime]", datetime.datetime.now().strftime("%Y%m%d%H%M%S")) - x = x.replace("[job_timestamp]", shared.state.job_timestamp) - if cmd_opts.hide_ui_dir_config: x = re.sub(r'^[\\/]+|\.{2,}[\\/]+|[\\/]+\.{2,}', '', x) -- cgit v1.2.3 From 0bb458f0ca06a7be27cf1a1003c536d1f06a5bd3 Mon Sep 17 00:00:00 2001 From: Milly Date: Wed, 5 Oct 2022 01:19:50 +0900 Subject: Removed duplicate image saving codes Use `modules.images.save_image()` instead. --- modules/images.py | 7 ++++--- modules/ui.py | 46 ++++++++++------------------------------------ 2 files changed, 14 insertions(+), 39 deletions(-) (limited to 'modules/images.py') diff --git a/modules/images.py b/modules/images.py index c2fadab9..810f1446 100644 --- a/modules/images.py +++ b/modules/images.py @@ -353,7 +353,7 @@ def get_next_sequence_number(path, basename): return result + 1 -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=""): +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): if short_filename or prompt is None or seed is None: file_decoration = "" elif opts.save_to_dirs: @@ -377,7 +377,8 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i else: pnginfo = 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 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 = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, seed, prompt).strip('\\ /') @@ -431,4 +432,4 @@ def save_image(image, path, basename, seed=None, prompt=None, extension='png', i with open(f"{fullfn_without_extension}.txt", "w", encoding="utf8") as file: file.write(info + "\n") - + return fullfn diff --git a/modules/ui.py b/modules/ui.py index 9620350f..4f18126f 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -35,7 +35,7 @@ import modules.codeformer_model import modules.styles import modules.generation_parameters_copypaste from modules import prompt_parser -from modules.images import apply_filename_pattern, get_next_sequence_number +from modules.images import save_image import modules.textual_inversion.ui # this is a fix for Windows users. Without it, javascript files will be served with text/html content-type and the bowser will not show any UI @@ -114,20 +114,13 @@ def save_files(js_data, images, index): p = MyObject(data) path = opts.outdir_save save_to_dirs = opts.use_save_to_dirs_for_ui - - if save_to_dirs: - dirname = apply_filename_pattern(opts.directories_filename_pattern or "[prompt_words]", p, p.seed, p.prompt) - path = os.path.join(opts.outdir_save, dirname) - - os.makedirs(path, exist_ok=True) - + extension: str = opts.samples_format + start_index = 0 if index > -1 and opts.save_selected_only and (index >= data["index_of_first_image"]): # ensures we are looking at a specific non-grid picture, and we have save_selected_only images = [images[index]] - infotexts = [data["infotexts"][index]] - else: - infotexts = data["infotexts"] + start_index = index with open(os.path.join(opts.outdir_save, "log.csv"), "a", encoding="utf8", newline='') as file: at_start = file.tell() == 0 @@ -135,37 +128,18 @@ def save_files(js_data, images, index): if at_start: writer.writerow(["prompt", "seed", "width", "height", "sampler", "cfgs", "steps", "filename", "negative_prompt"]) - file_decoration = opts.samples_filename_pattern or "[seed]-[prompt_spaces]" - if file_decoration != "": - file_decoration = "-" + file_decoration.lower() - file_decoration = apply_filename_pattern(file_decoration, p, p.seed, p.prompt) - truncated = (file_decoration[:240] + '..') if len(file_decoration) > 240 else file_decoration - filename_base = truncated - extension = opts.samples_format.lower() - - basecount = get_next_sequence_number(path, "") - for i, filedata in enumerate(images): - file_number = f"{basecount+i:05}" - filename = file_number + filename_base + f".{extension}" - filepath = os.path.join(path, filename) - - + for image_index, filedata in enumerate(images, start_index): if filedata.startswith("data:image/png;base64,"): filedata = filedata[len("data:image/png;base64,"):] image = Image.open(io.BytesIO(base64.decodebytes(filedata.encode('utf-8')))) - if opts.enable_pnginfo and extension == 'png': - pnginfo = PngImagePlugin.PngInfo() - pnginfo.add_text('parameters', infotexts[i]) - image.save(filepath, pnginfo=pnginfo) - else: - image.save(filepath, quality=opts.jpeg_quality) - if opts.enable_pnginfo and extension in ("jpg", "jpeg", "webp"): - piexif.insert(piexif.dump({"Exif": { - piexif.ExifIFD.UserComment: piexif.helper.UserComment.dump(infotexts[i], encoding="unicode") - }}), filepath) + is_grid = image_index < p.index_of_first_image + i = 0 if is_grid else (image_index - p.index_of_first_image) + + fullfn = save_image(image, path, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], extension=extension, info=p.infotexts[image_index], grid=is_grid, p=p, save_to_dirs=save_to_dirs) + filename = os.path.relpath(fullfn, path) filenames.append(filename) writer.writerow([data["prompt"], data["seed"], data["width"], data["height"], data["sampler"], data["cfg_scale"], data["steps"], filenames[0], data["negative_prompt"]]) -- cgit v1.2.3