Use bilinear filtering for resizing grayscale images (disabled by default)

* Lanczos is a good default when resizing, however, it is suboptimal for masks as it can introduce ringing artifacts. So use bilinear in these situations.
* Bicubic is better than Lanczos here, but can introduce "pinching" on corners. Nearest would be optimal for binary masks, but much worse if there's any blurring.
* Adds a new toggle to the img2img settings, which is disabled by default, as it does affect the shape of masks compared to Lanczos.
This commit is contained in:
Logan 2024-08-08 13:50:26 +10:00
parent 48239090f1
commit 02d4229ece
2 changed files with 4 additions and 3 deletions

View File

@ -24,7 +24,7 @@ from modules.paths_internal import roboto_ttf_file
from modules.shared import opts
LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
BILINEAR = (Image.Resampling.BILINEAR if hasattr(Image, 'Resampling') else Image.BILINEAR)
def get_font(fontsize: int):
try:
@ -268,7 +268,7 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None):
def resize(im, w, h):
if upscaler_name is None or upscaler_name == "None" or im.mode == 'L':
return im.resize((w, h), resample=LANCZOS)
return im.resize((w, h), resample=BILINEAR if im.mode == 'L' and opts.img2img_bilinear_grayscale_resize else LANCZOS)
scale = max(w / im.width, h / im.height)
@ -283,7 +283,7 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None):
im = upscaler.scaler.upscale(im, scale, upscaler.data_path)
if im.width != w or im.height != h:
im = im.resize((w, h), resample=LANCZOS)
im = im.resize((w, h), resample=BILINEAR if im.mode == 'L' and opts.img2img_bilinear_grayscale_resize else LANCZOS)
return im

View File

@ -227,6 +227,7 @@ options_templates.update(options_section(('img2img', "img2img", "sd"), {
"return_mask_composite": OptionInfo(False, "For inpainting, include masked composite in results for web"),
"img2img_batch_show_results_limit": OptionInfo(32, "Show the first N batch img2img results in UI", gr.Slider, {"minimum": -1, "maximum": 1000, "step": 1}).info('0: disable, -1: show all images. Too many images can cause lag'),
"overlay_inpaint": OptionInfo(True, "Overlay original for inpaint").info("when inpainting, overlay the original image over the areas that weren't inpainted."),
"img2img_bilinear_grayscale_resize": OptionInfo(False, "Use bilinear filtering for grayscale images (masks)").info("when resizing, grayscale images (which are almost always masks) will use bilinear filtering instead of Lanczos, which can introduce ringing artifacts"),
}))
options_templates.update(options_section(('optimizations', "Optimizations", "sd"), {