diff --git a/javascript/ui.js b/javascript/ui.js index f3860d2e..4944800b 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -35,13 +35,36 @@ function extract_image_from_gallery_extras(gallery){ return extract_image_from_gallery(gallery); } -function submit(){ - // this calls a function from progressbar.js - requestProgress() +function get_tab_index(tabId){ + var res = 0 + gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i){ + if(button.className.indexOf('bg-white') != -1) + res = i + }) + + return res +} + +function create_tab_index_args(tabId, args){ + var res = [] + for(var i=0; i 0: + left, right = os.path.splitext(filename) + filename = f"{left}-{n}{right}" + + processed_image.save(os.path.join(output_dir, filename)) + + +def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args): is_inpaint = mode == 1 - is_upscale = mode == 2 + is_batch = mode == 2 if is_inpaint: if mask_mode == 0: @@ -23,8 +63,8 @@ def img2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L') image = image.convert('RGB') else: - image = init_img - mask = init_mask + image = init_img_inpaint + mask = init_mask_inpaint else: image = init_img mask = None @@ -60,79 +100,19 @@ def img2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: resize_mode=resize_mode, denoising_strength=denoising_strength, inpaint_full_res=inpaint_full_res, + inpaint_full_res_padding=inpaint_full_res_padding, inpainting_mask_invert=inpainting_mask_invert, ) print(f"\nimg2img: {prompt}", file=shared.progress_print_out) p.extra_generation_params["Mask blur"] = mask_blur - if is_upscale: - initial_info = None - - processing.fix_seed(p) - seed = p.seed - - upscaler = shared.sd_upscalers[upscaler_index] - img = upscaler.upscale(init_img, init_img.width * 2, init_img.height * 2) - - devices.torch_gc() - - grid = images.split_grid(img, tile_w=width, tile_h=height, overlap=upscale_overlap) - - batch_size = p.batch_size - upscale_count = p.n_iter - p.n_iter = 1 - p.do_not_save_grid = True - p.do_not_save_samples = True - - work = [] - - for y, h, row in grid.tiles: - for tiledata in row: - work.append(tiledata[2]) - - batch_count = math.ceil(len(work) / batch_size) - state.job_count = batch_count * upscale_count - - print(f"SD upscaling will process a total of {len(work)} images tiled as {len(grid.tiles[0][2])}x{len(grid.tiles)} per upscale in a total of {state.job_count} batches.") - - result_images = [] - for n in range(upscale_count): - start_seed = seed + n - p.seed = start_seed - - work_results = [] - for i in range(batch_count): - p.batch_size = batch_size - p.init_images = work[i*batch_size:(i+1)*batch_size] - - state.job = f"Batch {i + 1 + n * batch_count} out of {state.job_count}" - processed = process_images(p) - - if initial_info is None: - initial_info = processed.info - - p.seed = processed.seed + 1 - work_results += processed.images - - image_index = 0 - for y, h, row in grid.tiles: - for tiledata in row: - tiledata[2] = work_results[image_index] if image_index < len(work_results) else Image.new("RGB", (p.width, p.height)) - image_index += 1 - - combined_image = images.combine_grid(grid) - result_images.append(combined_image) - - if opts.samples_save: - images.save_image(combined_image, p.outpath_samples, "", start_seed, prompt, opts.samples_format, info=initial_info, p=p) - - processed = Processed(p, result_images, seed, initial_info) + if is_batch: + process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, args) + processed = Processed(p, [], p.seed, "") else: - processed = modules.scripts.scripts_img2img.run(p, *args) - if processed is None: processed = process_images(p) diff --git a/modules/processing.py b/modules/processing.py index e844b7e2..f44c3f26 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -491,7 +491,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): sampler = None - def __init__(self, init_images=None, resize_mode=0, denoising_strength=0.75, mask=None, mask_blur=4, inpainting_fill=0, inpaint_full_res=True, inpainting_mask_invert=0, **kwargs): + def __init__(self, init_images=None, resize_mode=0, denoising_strength=0.75, mask=None, mask_blur=4, inpainting_fill=0, inpaint_full_res=True, inpaint_full_res_padding=0, inpainting_mask_invert=0, **kwargs): super().__init__(**kwargs) self.init_images = init_images @@ -505,6 +505,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): self.mask_blur = mask_blur self.inpainting_fill = inpainting_fill self.inpaint_full_res = inpaint_full_res + self.inpaint_full_res_padding = inpaint_full_res_padding self.inpainting_mask_invert = inpainting_mask_invert self.mask = None self.nmask = None @@ -527,7 +528,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing): if self.inpaint_full_res: self.mask_for_overlay = self.image_mask mask = self.image_mask.convert('L') - crop_region = masking.get_crop_region(np.array(mask), opts.upscale_at_full_resolution_padding) + crop_region = masking.get_crop_region(np.array(mask), self.inpaint_full_res_padding) crop_region = masking.expand_crop_region(crop_region, self.width, self.height, mask.width, mask.height) x1, y1, x2, y2 = crop_region diff --git a/modules/scripts.py b/modules/scripts.py index 0e0b949b..9ab207dc 100644 --- a/modules/scripts.py +++ b/modules/scripts.py @@ -143,7 +143,6 @@ class ScriptRunner: return inputs - def run(self, p: StableDiffusionProcessing, *args): script_index = args[0] diff --git a/modules/shared.py b/modules/shared.py index 0a852838..841a9877 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -147,14 +147,13 @@ class Options: "save_txt": OptionInfo(False, "Create a text file next to every image with generation parameters."), "ESRGAN_tile": OptionInfo(192, "Tile size for ESRGAN upscalers. 0 = no tiling.", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}), "ESRGAN_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for ESRGAN upscalers. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}), - "realesrgan_enabled_models": OptionInfo(["Real-ESRGAN 4x plus", "Real-ESRGAN 4x plus anime 6B"],"Select which RealESRGAN models to show in the web UI. (Requires restart)", gr.CheckboxGroup, lambda: {"choices": realesrgan_models_names()}), + "realesrgan_enabled_models": OptionInfo(["Real-ESRGAN 4x plus", "Real-ESRGAN 4x plus anime 6B"], "Select which RealESRGAN models to show in the web UI. (Requires restart)", gr.CheckboxGroup, lambda: {"choices": realesrgan_models_names()}), "SWIN_tile": OptionInfo(192, "Tile size for all SwinIR.", gr.Slider, {"minimum": 16, "maximum": 512, "step": 16}), "SWIN_tile_overlap": OptionInfo(8, "Tile overlap, in pixels for SwinIR. Low values = visible seam.", gr.Slider, {"minimum": 0, "maximum": 48, "step": 1}), "ldsr_steps": OptionInfo(100, "LDSR processing steps. Lower = faster", gr.Slider, {"minimum": 1, "maximum": 200, "step": 1}), "ldsr_pre_down":OptionInfo(1, "LDSR Pre-process downssample scale. 1 = no down-sampling, 4 = 1/4 scale.", gr.Slider, {"minimum": 1, "maximum": 4, "step": 1}), "ldsr_post_down":OptionInfo(1, "LDSR Post-process down-sample scale. 1 = no down-sampling, 4 = 1/4 scale.", gr.Slider, {"minimum": 1, "maximum": 4, "step": 1}), "random_artist_categories": OptionInfo([], "Allowed categories for random artists selection when using the Roll button", gr.CheckboxGroup, {"choices": artist_db.categories()}), - "upscale_at_full_resolution_padding": OptionInfo(16, "Inpainting at full resolution: padding, in pixels, for the masked region.", gr.Slider, {"minimum": 0, "maximum": 128, "step": 4}), "upscaler_for_hires_fix": OptionInfo(None, "Upscaler for highres. fix", gr.Radio, lambda: {"choices": [x.name for x in sd_upscalers]}), "show_progressbar": OptionInfo(True, "Show progressbar"), "show_progress_every_n_steps": OptionInfo(0, "Show show image creation progress every N sampling steps. Set 0 to disable.", gr.Slider, {"minimum": 0, "maximum": 32, "step": 1}), diff --git a/modules/ui.py b/modules/ui.py index 572dcfb9..3c898bd2 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -527,36 +527,47 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): progressbar = gr.HTML(elem_id="progressbar") img2img_preview = gr.Image(elem_id='img2img_preview', visible=False) setup_progressbar(progressbar, img2img_preview) - + with gr.Row().style(equal_height=False): with gr.Column(variant='panel'): - with gr.Group(): - switch_mode = gr.Radio(label='Mode', elem_id="img2img_mode", choices=['Redraw whole image', 'Inpaint a part of image', '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") - init_mask = gr.Image(label="Mask", source="upload", interactive=True, type="pil", visible=False) - init_img_with_mask_comment = gr.HTML(elem_id="mask_bug_info", value="if the editor shows ERROR, switch to another tab and back, then to another img2img mode above and back", 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") + with gr.Tabs(elem_id="mode_img2img") as tabs_img2img_mode: + with gr.TabItem('img2img'): + init_img = gr.Image(label="Image for img2img", show_label=False, source="upload", interactive=True, type="pil") + + with gr.TabItem('Inpaint'): + init_img_with_mask = gr.Image(label="Image for inpainting with mask", show_label=False, elem_id="img2maskimg", source="upload", interactive=True, type="pil", tool="sketch", image_mode="RGBA") + init_img_with_mask_comment = gr.HTML(elem_id="mask_bug_info", value="if the editor shows ERROR, switch to another tab and back, then to \"Upload mask\" mode above and back") + + init_img_inpaint = gr.Image(label="Image for img2img", show_label=False, source="upload", interactive=True, type="pil", visible=False) + init_mask_inpaint = gr.Image(label="Mask", source="upload", interactive=True, type="pil", visible=False) + + mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4) + + with gr.Row(): + mask_mode = gr.Radio(label="Mask mode", show_label=False, choices=["Draw mask", "Upload mask"], type="index", value="Draw mask") + inpainting_mask_invert = gr.Radio(label='Masking mode', show_label=False, choices=['Inpaint masked', 'Inpaint not masked'], value='Inpaint masked', type="index") + + inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='fill', type="index") + + with gr.Row(): + inpaint_full_res = gr.Checkbox(label='Inpaint at full resolution', value=False) + inpaint_full_res_padding = gr.Slider(label='Inpaint at full resolution padding, pixels', minimum=0, maximum=256, step=4, value=32) + + with gr.TabItem('Batch img2img'): + gr.HTML("

Process images in a directory on the same machine where the server is running.

") + img2img_batch_input_dir = gr.Textbox(label="Input directory") + img2img_batch_output_dir = gr.Textbox(label="Output directory") + + 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") 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") - mask_blur = gr.Slider(label='Mask blur', minimum=0, maximum=64, step=1, value=4, visible=False) - inpainting_fill = gr.Radio(label='Masked content', choices=['fill', 'original', 'latent noise', 'latent nothing'], value='fill', type="index", visible=False) - - with gr.Row(): - inpaint_full_res = gr.Checkbox(label='Inpaint at full resolution', value=False, visible=False) - inpainting_mask_invert = gr.Radio(label='Masking mode', choices=['Inpaint masked', 'Inpaint not masked'], value='Inpaint masked', type="index", visible=False) with gr.Row(): restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1) tiling = gr.Checkbox(label='Tiling', value=False) - sd_upscale_overlap = gr.Slider(minimum=0, maximum=256, step=16, label='Tile overlap', value=64, visible=False) - - with gr.Row(): - sd_upscale_upscaler_name = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index", visible=False) with gr.Row(): batch_count = gr.Slider(minimum=1, maximum=cmd_opts.max_batch_count, step=1, label='Batch count', value=1) @@ -589,7 +600,6 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): img2img_send_to_extras = gr.Button('Send to extras') img2img_save_style = gr.Button('Save prompt as style') - with gr.Group(): html_info = gr.HTML() generation_info = gr.Textbox(visible=False) @@ -597,70 +607,36 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False) connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True) - def apply_mode(mode, uploadmask): - is_classic = mode == 0 - is_inpaint = mode == 1 - is_upscale = mode == 2 - - return { - 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_img_with_mask_comment: 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), - sd_upscale_upscaler_name: gr_show(is_upscale), - sd_upscale_overlap: gr_show(is_upscale), - inpaint_full_res: gr_show(is_inpaint), - inpainting_mask_invert: gr_show(is_inpaint), - img2img_interrogate: gr_show(not is_inpaint), - } - - switch_mode.change( - apply_mode, - inputs=[switch_mode, mask_mode], + mask_mode.change( + lambda mode, img: { + #init_img_with_mask: gr.Image.update(visible=mode == 0, value=img["image"]), + init_img_with_mask: gr_show(mode == 0), + init_img_with_mask_comment: gr_show(mode == 0), + init_img_inpaint: gr_show(mode == 1), + init_mask_inpaint: gr_show(mode == 1), + }, + inputs=[mask_mode, init_img_with_mask], outputs=[ - init_img, init_img_with_mask, init_img_with_mask_comment, - init_mask, - mask_mode, - mask_blur, - inpainting_fill, - sd_upscale_upscaler_name, - sd_upscale_overlap, - inpaint_full_res, - inpainting_mask_invert, - img2img_interrogate, - ] - ) - - 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, + init_img_inpaint, + init_mask_inpaint, ], ) img2img_args = dict( fn=img2img, - _js="submit", + _js="submit_img2img", inputs=[ + dummy_component, img2img_prompt, img2img_negative_prompt, img2img_prompt_style, img2img_prompt_style2, init_img, init_img_with_mask, - init_mask, + init_img_inpaint, + init_mask_inpaint, mask_mode, steps, sampler_index, @@ -668,7 +644,6 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): inpainting_fill, restore_faces, tiling, - switch_mode, batch_count, batch_size, cfg_scale, @@ -678,10 +653,11 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): height, width, resize_mode, - sd_upscale_upscaler_name, - sd_upscale_overlap, inpaint_full_res, + inpaint_full_res_padding, inpainting_mask_invert, + img2img_batch_input_dir, + img2img_batch_output_dir, ] + custom_inputs, outputs=[ img2img_gallery, @@ -748,7 +724,7 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): with gr.Blocks(analytics_enabled=False) as extras_interface: with gr.Row().style(equal_height=False): with gr.Column(variant='panel'): - with gr.Tabs(): + with gr.Tabs(elem_id="mode_extras"): with gr.TabItem('Single Image'): image = gr.Image(label="Source", source="upload", interactive=True, type="pil") @@ -778,9 +754,11 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): html_info_x = gr.HTML() html_info = gr.HTML() - extras_args = dict( + submit.click( fn=run_extras, + _js="get_extras_tab_index", inputs=[ + dummy_component, image, image_batch, gfpgan_visibility, @@ -798,8 +776,6 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): ] ) - submit.click(**extras_args) - pnginfo_interface = gr.Interface( wrap_gradio_call(run_pnginfo), inputs=[ @@ -929,6 +905,12 @@ def create_ui(txt2img, img2img, run_extras, run_pnginfo): outputs=[init_img_with_mask], ) + tabs_img2img_mode.change( + fn=lambda x: x, + inputs=[init_img_with_mask], + outputs=[init_img_with_mask], + ) + send_to_img2img.click( fn=lambda x: image_from_url_text(x), _js="extract_image_from_gallery_img2img", diff --git a/scripts/batch.py b/scripts/batch.py deleted file mode 100644 index 1af4a7bc..00000000 --- a/scripts/batch.py +++ /dev/null @@ -1,59 +0,0 @@ -import math -import os -import sys -import traceback - -import modules.scripts as scripts -import gradio as gr - -from modules.processing import Processed, process_images -from PIL import Image -from modules.shared import opts, cmd_opts, state - - -class Script(scripts.Script): - def title(self): - return "Batch processing" - - def show(self, is_img2img): - return is_img2img - - def ui(self, is_img2img): - input_dir = gr.Textbox(label="Input directory", lines=1) - output_dir = gr.Textbox(label="Output directory", lines=1) - - return [input_dir, output_dir] - - def run(self, p, input_dir, output_dir): - images = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)] - - batch_count = math.ceil(len(images) / p.batch_size) - print(f"Will process {len(images)} images in {batch_count} batches.") - - p.batch_count = 1 - p.do_not_save_grid = True - p.do_not_save_samples = True - - state.job_count = batch_count - - for batch_no in range(batch_count): - batch_images = [] - for path in images[batch_no*p.batch_size:(batch_no+1)*p.batch_size]: - try: - img = Image.open(path) - batch_images.append((img, path)) - except: - print(f"Error processing {path}:", file=sys.stderr) - print(traceback.format_exc(), file=sys.stderr) - - if len(batch_images) == 0: - continue - - state.job = f"{batch_no} out of {batch_count}: {batch_images[0][1]}" - p.init_images = [x[0] for x in batch_images] - proc = process_images(p) - for image, (_, path) in zip(proc.images, batch_images): - filename = os.path.basename(path) - image.save(os.path.join(output_dir, filename)) - - return Processed(p, [], p.seed, "") diff --git a/scripts/sd_upscale.py b/scripts/sd_upscale.py new file mode 100644 index 00000000..b87a145b --- /dev/null +++ b/scripts/sd_upscale.py @@ -0,0 +1,93 @@ +import math + +import modules.scripts as scripts +import gradio as gr +from PIL import Image + +from modules import processing, shared, sd_samplers, images, devices +from modules.processing import Processed +from modules.shared import opts, cmd_opts, state + + +class Script(scripts.Script): + def title(self): + return "SD upscale" + + def show(self, is_img2img): + return is_img2img + + def ui(self, is_img2img): + info = gr.HTML("

Will upscale the image to twice the dimensions; use width and height sliders to set tile size

") + overlap = gr.Slider(minimum=0, maximum=256, step=16, label='Tile overlap', value=64, visible=False) + upscaler_index = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name, type="index", visible=False) + + return [info, overlap, upscaler_index] + + def run(self, p, _, overlap, upscaler_index): + processing.fix_seed(p) + upscaler = shared.sd_upscalers[upscaler_index] + + p.extra_generation_params["SD upscale overlap"] = overlap + p.extra_generation_params["SD upscale upscaler"] = upscaler.name + + initial_info = None + seed = p.seed + + init_img = p.init_images[0] + img = upscaler.upscale(init_img, init_img.width * 2, init_img.height * 2) + + devices.torch_gc() + + grid = images.split_grid(img, tile_w=p.width, tile_h=p.height, overlap=overlap) + + batch_size = p.batch_size + upscale_count = p.n_iter + p.n_iter = 1 + p.do_not_save_grid = True + p.do_not_save_samples = True + + work = [] + + for y, h, row in grid.tiles: + for tiledata in row: + work.append(tiledata[2]) + + batch_count = math.ceil(len(work) / batch_size) + state.job_count = batch_count * upscale_count + + print(f"SD upscaling will process a total of {len(work)} images tiled as {len(grid.tiles[0][2])}x{len(grid.tiles)} per upscale in a total of {state.job_count} batches.") + + result_images = [] + for n in range(upscale_count): + start_seed = seed + n + p.seed = start_seed + + work_results = [] + for i in range(batch_count): + p.batch_size = batch_size + p.init_images = work[i*batch_size:(i+1)*batch_size] + + state.job = f"Batch {i + 1 + n * batch_count} out of {state.job_count}" + processed = processing.process_images(p) + + if initial_info is None: + initial_info = processed.info + + p.seed = processed.seed + 1 + work_results += processed.images + + image_index = 0 + for y, h, row in grid.tiles: + for tiledata in row: + tiledata[2] = work_results[image_index] if image_index < len(work_results) else Image.new("RGB", (p.width, p.height)) + image_index += 1 + + combined_image = images.combine_grid(grid) + result_images.append(combined_image) + + if opts.samples_save: + images.save_image(combined_image, p.outpath_samples, "", start_seed, p.prompt, opts.samples_format, info=initial_info, p=p) + + processed = Processed(p, result_images, seed, initial_info) + + return processed diff --git a/style.css b/style.css index 655a00e5..de5f94a6 100644 --- a/style.css +++ b/style.css @@ -97,6 +97,11 @@ background: transparent; } +.my-4{ + margin-top: 0; + margin-bottom: 0; +} + #toprow div{ border: none; gap: 0; @@ -198,7 +203,8 @@ input[type="range"]{ #mask_bug_info { text-align: center; display: block; - margin-bottom: 0.5em; + margin-top: -0.75em; + margin-bottom: -0.75em; } #txt2img_negative_prompt, #img2img_negative_prompt{