From d714ea4c41e4e7c0dc4730d9ea137d134691c0a2 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Fri, 9 Sep 2022 19:43:16 +0300 Subject: [PATCH] ability to upload mask for inpainting --- modules/img2img.py | 15 ++++++++++----- modules/ui.py | 34 +++++++++++++++++++++++++++++----- style.css | 4 ++++ 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/modules/img2img.py b/modules/img2img.py index 54023df5f..008e86882 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -11,16 +11,21 @@ from modules.ui import plaintext_to_html import modules.images as images import modules.scripts -def img2img(prompt: str, negative_prompt: str, init_img, init_img_with_mask, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, mode: int, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, denoising_strength_change_factor: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, height: int, width: int, resize_mode: int, upscaler_index: str, upscale_overlap: int, inpaint_full_res: bool, inpainting_mask_invert: int, *args): +def img2img(prompt: str, negative_prompt: str, init_img, init_img_with_mask, init_mask, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, mode: int, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, denoising_strength_change_factor: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, height: int, width: int, resize_mode: int, upscaler_index: str, upscale_overlap: int, inpaint_full_res: bool, inpainting_mask_invert: int, *args): is_inpaint = mode == 1 is_loopback = mode == 2 is_upscale = mode == 3 if is_inpaint: - image = init_img_with_mask['image'] - alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1') - mask = ImageChops.lighter(alpha_mask, init_img_with_mask['mask'].convert('L')).convert('RGBA') - image = image.convert('RGB') + if mask_mode == 0: + image = init_img_with_mask['image'] + mask = init_img_with_mask['mask'] + alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1') + mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L') + image = image.convert('RGB') + else: + image = init_img + mask = init_mask else: image = init_img mask = None diff --git a/modules/ui.py b/modules/ui.py index 6784de57c..65076edbd 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -360,7 +360,11 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): switch_mode = gr.Radio(label='Mode', elem_id="img2img_mode", choices=['Redraw whole image', 'Inpaint a part of image', 'Loopback', 'SD upscale'], value='Redraw whole image', type="index", show_label=False) init_img = gr.Image(label="Image for img2img", source="upload", interactive=True, type="pil") init_img_with_mask = gr.Image(label="Image for inpainting with mask", elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", visible=False, image_mode="RGBA") - resize_mode = gr.Radio(label="Resize mode", show_label=False, choices=["Just resize", "Crop and resize", "Resize and fill"], type="index", value="Just resize") + init_mask = gr.Image(label="Mask", source="upload", interactive=True, type="pil", visible=False) + + with gr.Row(): + resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", show_label=False, choices=["Just resize", "Crop and resize", "Resize and fill"], type="index", value="Just resize") + mask_mode = gr.Radio(label="Mask mode", show_label=False, choices=["Draw mask", "Upload mask"], type="index", value="Draw mask") steps = gr.Slider(minimum=1, maximum=150, step=1, label="Sampling Steps", value=20) sampler_index = gr.Radio(label='Sampling method', choices=[x.name for x in samplers_for_img2img], value=samplers_for_img2img[0].name, type="index") @@ -416,15 +420,17 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): html_info = gr.HTML() generation_info = gr.Textbox(visible=False) - def apply_mode(mode): + def apply_mode(mode, uploadmask): is_classic = mode == 0 is_inpaint = mode == 1 is_loopback = mode == 2 is_upscale = mode == 3 return { - init_img: gr_show(not is_inpaint), - init_img_with_mask: gr_show(is_inpaint), + init_img: gr_show(not is_inpaint or (is_inpaint and uploadmask == 1)), + init_img_with_mask: gr_show(is_inpaint and uploadmask == 0), + init_mask: gr_show(is_inpaint and uploadmask == 1), + mask_mode: gr_show(is_inpaint), mask_blur: gr_show(is_inpaint), inpainting_fill: gr_show(is_inpaint), batch_count: gr_show(not is_upscale), @@ -438,10 +444,12 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): switch_mode.change( apply_mode, - inputs=[switch_mode], + inputs=[switch_mode, mask_mode], outputs=[ init_img, init_img_with_mask, + init_mask, + mask_mode, mask_blur, inpainting_fill, batch_count, @@ -454,6 +462,20 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): ] ) + mask_mode.change( + lambda mode: { + init_img: gr_show(mode == 1), + init_img_with_mask: gr_show(mode == 0), + init_mask: gr_show(mode == 1), + }, + inputs=[mask_mode], + outputs=[ + init_img, + init_img_with_mask, + init_mask, + ], + ) + img2img_args = dict( fn=img2img, _js="submit", @@ -462,6 +484,8 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): negative_prompt, init_img, init_img_with_mask, + init_mask, + mask_mode, steps, sampler_index, mask_blur, diff --git a/style.css b/style.css index 9f847e4ce..57b3665de 100644 --- a/style.css +++ b/style.css @@ -19,6 +19,10 @@ max-width: 4em; } +#resize_mode{ + flex: 1.5; +} + button{ align-self: stretch !important; }