create_ui and process refactor

This commit is contained in:
Vladimir Mandic
2023-12-15 18:53:03 -05:00
parent e6d95fd0a7
commit 936cf9786c
14 changed files with 319 additions and 268 deletions
+27 -18
View File
@@ -8,7 +8,6 @@
- **AnimateDiff** can now be used with *second pass* - enhance, upscale and hires your videos!
- **IP Adapter** add support for `ip-adapter-plus_sd15`, `ip-adapter-plus-face_sd15` and `ip-adapter-full-face_sd15`
additionally, ip-adapter can now be used in xyz-grid
- **HDR controls** are now batch-aware for enhancement of multiple images or video frames
- [Playground v1](https://huggingface.co/playgroundai/playground-v1), [Playground v2 256](https://huggingface.co/playgroundai/playground-v2-256px-base), [Playground v2 512](https://huggingface.co/playgroundai/playground-v2-512px-base), [Playground v2 1024](https://huggingface.co/playgroundai/playground-v2-1024px-aesthetic) model support
- simply select from *networks -> reference* and use as usual
- [DemoFusion](https://github.com/PRIS-CV/DemoFusion) run your SDXL generations at any resolution!
@@ -37,28 +36,38 @@
- **Extra networks** new *settting -> extra networks -> build info on first access*
indexes all networks on first access instead of server startup
- **IPEX**, thanks @disty0
- update to **Torch 2.1**
if you get file not found errors, set DISABLE_IPEXRUN=1 and run the webui with --reinstall
- update to **Torch 2.1**
if you get file not found errors, set DISABLE_IPEXRUN=1 and run the webui with --reinstall
- built-in *MKL* and *DPCPP* for IPEX, no need to install OneAPI anymore
- fix IPEX Optimize not applying with Diffusers backend
- disable 32 bit workarounds if the GPU supports 64 bit
- add DISABLE_IPEXRUN environment variable
- compatibility improvements
- **OpenVINO**, thanks @disty0
- Add *Directory for OpenVINO cache* option to *System Paths*
- Remove Intel ARC specific 1024x1024 workaround
- **Inpaint** add option `apply_overlay` to control if inpaint result should be applied as overlay or as-is
can remove artifacts and hard edges of inpaint area but also remove some details from original
- disable google fonts check on server startup
- fix torchvision/basicsr compatibility
- fix extra networks sort
- add hdr settings to metadata
- improve handling of long filenames and filenames during batch processing
- do not set preview samples when using via api
- avoid unnecessary resizes in img2img and inpaint
- updated `cli/simple-txt2img.py` and `cli/simple-img2img.py` scripts
- save `params.txt` regardless of image save status
- update built-in log monitor in ui, thanks @midcoastal
- **OpenVINO**, thanks @disty0
- add *Directory for OpenVINO cache* option to *System Paths*
- remove Intel ARC specific 1024x1024 workaround
- **UI**
- more dynamic controls depending on the backend (original or diffusers)
controls that are not applicable in current mode are now hidden
- allow setting of resize method directly in image tab
(previously via settings -> upscaler_for_img2img)
- **HDR controls**
- batch-aware for enhancement of multiple images or video frames
- available in image tab
- **Other**
- **Inpaint** add option `apply_overlay` to control if inpaint result should be applied as overlay or as-is
can remove artifacts and hard edges of inpaint area but also remove some details from original
- **chaiNNer** fix NaN issues due to autocast
- **Extra Networks** fix sort
- disable google fonts check on server startup
- fix torchvision/basicsr compatibility
- add hdr settings to metadata
- improve handling of long filenames and filenames during batch processing
- do not set preview samples when using via api
- avoid unnecessary resizes in img2img and inpaint
- updated `cli/simple-txt2img.py` and `cli/simple-img2img.py` scripts
- save `params.txt` regardless of image save status
- update built-in log monitor in ui, thanks @midcoastal
## Update for 2023-12-04
+4 -4
View File
@@ -226,10 +226,10 @@
{"id":"","label":"Inpaint batch input directory","localized":"","hint":""},
{"id":"","label":"Inpaint batch output directory","localized":"","hint":""},
{"id":"","label":"Inpaint batch mask directory","localized":"","hint":""},
{"id":"","label":"Resize fixed","localized":"","hint":"Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio"},
{"id":"","label":"Crop and resize","localized":"","hint":"Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out"},
{"id":"","label":"Resize and fill","localized":"","hint":"Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors"},
{"id":"","label":"Latent upscale","localized":"","hint":""},
{"id":"","label":"Fixed","localized":"","hint":"Resize image to target resolution. Unless height and width match, you will get incorrect aspect ratio"},
{"id":"","label":"Crop","localized":"","hint":"Resize the image so that entirety of target resolution is filled with the image. Crop parts that stick out"},
{"id":"","label":"Fill","localized":"","hint":"Resize the image so that entirety of image is inside target resolution. Fill empty space with image's colors"},
{"id":"","label":"Latent","localized":"","hint":""},
{"id":"","label":"Mask blur","localized":"","hint":"How much to blur the mask before processing, in pixels"},
{"id":"","label":"Mask transparency","localized":"","hint":""},
{"id":"","label":"Inpaint masked","localized":"","hint":""},
+1 -1
View File
@@ -52,7 +52,7 @@ textarea { overflow-y: auto !important; }
.small-accordion .form { min-width: var(--left-column) !important; max-width: max-content; }
.small-accordion .label-wrap .icon { margin-right: 1.6em; margin-left: 0.6em; color: var(--button-primary-border-color); }
.small-accordion .label-wrap { padding: 16px 0px 8px 0px; margin: 0; border-top: 2px solid var(--button-secondary-border-color); }
.small-accordion { width: fit-content !important; padding-left: 0 !important; }
.small-accordion { width: fit-content !important; min-width: fit-content !important; padding-left: 0 !important; }
.extension-script { max-width: 48vw; }
button.custom-button{ border-radius: var(--button-large-radius); padding: var(--button-large-padding); font-weight: var(--button-large-text-weight); border: var(--button-border-width) solid var(--button-secondary-border-color);
background: var(--button-secondary-background-fill); color: var(--button-secondary-text-color); font-size: var(--button-large-text-size);
+1 -1
View File
@@ -215,7 +215,7 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, output_type
Resizes an image with the specified resize_mode, width, and height.
Args:
resize_mode: The mode to use when resizing the image.
0: No resie
0: No resize
1: Resize the image to the specified width and height.
2: Resize the image to fill the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, cropping the excess.
3: Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, filling empty with data from image.
+37 -2
View File
@@ -103,13 +103,43 @@ def process_batch(p, input_files, input_dir, output_dir, inpaint_mask_dir, args)
shared.log.debug(f'Processed: images={len(batch_image_files)} memory={memory_stats()} batch')
def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, latent_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, full_quality: bool, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, diffusers_guidance_rescale: float, refiner_steps: int, refiner_start: float, clip_skip: int, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_files: list, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): # pylint: disable=unused-argument
def img2img(id_task: str, mode: int,
prompt, negative_prompt, prompt_styles,
init_img,
sketch,
init_img_with_mask,
inpaint_color_sketch,
inpaint_color_sketch_orig,
init_img_inpaint,
init_mask_inpaint,
steps,
sampler_index, latent_index,
mask_blur, mask_alpha,
inpainting_fill,
full_quality, restore_faces, tiling,
n_iter, batch_size,
cfg_scale, image_cfg_scale,
diffusers_guidance_rescale,
refiner_steps,
refiner_start,
clip_skip,
denoising_strength,
seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w,
selected_scale_tab,
height, width,
scale_by,
resize_mode, resize_name,
inpaint_full_res, inpaint_full_res_padding, inpainting_mask_invert,
img2img_batch_files, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir,
hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry,
override_settings_texts,
*args): # pylint: disable=unused-argument
if shared.sd_model is None:
shared.log.warning('Model not loaded')
return [], '', '', 'Error: model not loaded'
debug(f'img2img: id_task={id_task}|mode={mode}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|init_img={init_img}|sketch={sketch}|init_img_with_mask={init_img_with_mask}|inpaint_color_sketch={inpaint_color_sketch}|inpaint_color_sketch_orig={inpaint_color_sketch_orig}|init_img_inpaint={init_img_inpaint}|init_mask_inpaint={init_mask_inpaint}|steps={steps}|sampler_index={sampler_index}|latent_index={latent_index}|mask_blur={mask_blur}|mask_alpha={mask_alpha}|inpainting_fill={inpainting_fill}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|image_cfg_scale={image_cfg_scale}|clip_skip={clip_skip}|denoising_strength={denoising_strength}|seed={seed}|subseed{subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|selected_scale_tab={selected_scale_tab}|height={height}|width={width}|scale_by={scale_by}|resize_mode={resize_mode}|inpaint_full_res={inpaint_full_res}|inpaint_full_res_padding={inpaint_full_res_padding}|inpainting_mask_invert={inpainting_mask_invert}|img2img_batch_files={img2img_batch_files}|img2img_batch_input_dir={img2img_batch_input_dir}|img2img_batch_output_dir={img2img_batch_output_dir}|img2img_batch_inpaint_mask_dir={img2img_batch_inpaint_mask_dir}|override_settings_texts={override_settings_texts}')
debug(f'img2img: id_task={id_task}|mode={mode}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|init_img={init_img}|sketch={sketch}|init_img_with_mask={init_img_with_mask}|inpaint_color_sketch={inpaint_color_sketch}|inpaint_color_sketch_orig={inpaint_color_sketch_orig}|init_img_inpaint={init_img_inpaint}|init_mask_inpaint={init_mask_inpaint}|steps={steps}|sampler_index={sampler_index}|latent_index={latent_index}|mask_blur={mask_blur}|mask_alpha={mask_alpha}|inpainting_fill={inpainting_fill}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|image_cfg_scale={image_cfg_scale}|clip_skip={clip_skip}|denoising_strength={denoising_strength}|seed={seed}|subseed{subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|selected_scale_tab={selected_scale_tab}|height={height}|width={width}|scale_by={scale_by}|resize_mode={resize_mode}|resize_name={resize_name}|inpaint_full_res={inpaint_full_res}|inpaint_full_res_padding={inpaint_full_res_padding}|inpainting_mask_invert={inpainting_mask_invert}|img2img_batch_files={img2img_batch_files}|img2img_batch_input_dir={img2img_batch_input_dir}|img2img_batch_output_dir={img2img_batch_output_dir}|img2img_batch_inpaint_mask_dir={img2img_batch_inpaint_mask_dir}|override_settings_texts={override_settings_texts}')
if mode == 5:
if img2img_batch_files is None or len(img2img_batch_files) == 0:
@@ -159,6 +189,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
image = init_img_inpaint
mask = init_mask_inpaint
else:
shared.log.error(f'Image processing unknown mode: {mode}')
image = None
mask = None
if image is not None:
@@ -197,6 +228,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
mask_blur=mask_blur,
inpainting_fill=inpainting_fill,
resize_mode=resize_mode,
resize_name=resize_name,
denoising_strength=denoising_strength,
image_cfg_scale=image_cfg_scale,
diffusers_guidance_rescale=diffusers_guidance_rescale,
@@ -205,6 +237,9 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
inpaint_full_res=inpaint_full_res,
inpaint_full_res_padding=inpaint_full_res_padding,
inpainting_mask_invert=inpainting_mask_invert,
hdr_clamp=hdr_clamp, hdr_boundary=hdr_boundary, hdr_threshold=hdr_threshold,
hdr_center=hdr_center, hdr_channel_shift=hdr_channel_shift, hdr_full_shift=hdr_full_shift,
hdr_maximize=hdr_maximize, hdr_max_center=hdr_max_center, hdr_max_boundry=hdr_max_boundry,
override_settings=override_settings,
)
if selected_scale_tab == 1 and resize_mode != 0:
+20 -11
View File
@@ -126,7 +126,7 @@ class StableDiffusionProcessing:
"""
The first set of paramaters: sd_models -> do_not_reload_embeddings represent the minimum required to create a StableDiffusionProcessing
"""
def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, latent_sampler: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, image_cfg_scale: float = None, clip_skip: int = 1, width: int = 512, height: int = 512, full_quality: bool = True, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, diffusers_guidance_rescale: float = 0.7, hdr_clamp: bool = False, hdr_boundary: float = 4.0, hdr_threshold: float = 3.5, hdr_center: bool = False, hdr_channel_shift: float = 0.8, hdr_full_shift: float = 0.8, hdr_maximize: bool = False, hdr_max_center: float = 0.6, hdr_max_boundry: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): # pylint: disable=unused-argument
def __init__(self, sd_model=None, outpath_samples=None, outpath_grids=None, prompt: str = "", styles: List[str] = None, seed: int = -1, subseed: int = -1, subseed_strength: float = 0, seed_resize_from_h: int = -1, seed_resize_from_w: int = -1, seed_enable_extras: bool = True, sampler_name: str = None, latent_sampler: str = None, batch_size: int = 1, n_iter: int = 1, steps: int = 50, cfg_scale: float = 7.0, image_cfg_scale: float = None, clip_skip: int = 1, width: int = 512, height: int = 512, full_quality: bool = True, restore_faces: bool = False, tiling: bool = False, do_not_save_samples: bool = False, do_not_save_grid: bool = False, extra_generation_params: Dict[Any, Any] = None, overlay_images: Any = None, negative_prompt: str = None, eta: float = None, do_not_reload_embeddings: bool = False, denoising_strength: float = 0, diffusers_guidance_rescale: float = 0.7, resize_mode: int = 0, resize_name: str = 'None', scale_by: float = 0, selected_scale_tab: int = 0, hdr_clamp: bool = False, hdr_boundary: float = 4.0, hdr_threshold: float = 3.5, hdr_center: bool = False, hdr_channel_shift: float = 0.8, hdr_full_shift: float = 0.8, hdr_maximize: bool = False, hdr_max_center: float = 0.6, hdr_max_boundry: float = 1.0, override_settings: Dict[str, Any] = None, override_settings_restore_afterwards: bool = True, sampler_index: int = None, script_args: list = None): # pylint: disable=unused-argument
self.outpath_samples: str = outpath_samples
self.outpath_grids: str = outpath_grids
self.prompt: str = prompt
@@ -145,6 +145,7 @@ class StableDiffusionProcessing:
self.steps: int = steps
self.hr_second_pass_steps = 0
self.cfg_scale: float = cfg_scale
self.scale_by: float = scale_by
self.image_cfg_scale = image_cfg_scale
self.diffusers_guidance_rescale = diffusers_guidance_rescale
if devices.backend == "ipex" and width == 1024 and height == 1024:
@@ -197,7 +198,8 @@ class StableDiffusionProcessing:
self.refiner_prompt = ''
self.refiner_negative = ''
self.ops = []
self.resize_mode: int = 0
self.resize_mode: int = resize_mode
self.resize_name: str = resize_name
self.ddim_discretize = shared.opts.ddim_discretize
self.s_min_uncond = shared.opts.s_min_uncond
self.s_churn = shared.opts.s_churn
@@ -636,9 +638,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No
args["Denoising strength"] = getattr(p, 'denoising_strength', None)
# lookup by index
if getattr(p, 'resize_mode', None) is not None:
RESIZE_MODES = ["None", "Resize fixed", "Crop and resize", "Resize and fill", "Latent upscale"]
args['Resize mode'] = RESIZE_MODES[p.resize_mode]
# TODO missing-by-index: inpainting_fill, inpaint_full_res, inpainting_mask_invert
args['Resize mode'] = shared.resize_modes[p.resize_mode]
if 'face' in p.ops:
args["Face restoration"] = shared.opts.face_restoration_model
if 'color' in p.ops:
@@ -846,6 +846,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
with devices.autocast():
p.init(p.all_prompts, p.all_seeds, p.all_subseeds)
extra_network_data = None
debug(f'Processing inner: args={vars(p)}')
for n in range(p.n_iter):
p.iteration = n
if shared.state.skipped:
@@ -1199,10 +1200,11 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
def __init__(self, init_images: list = None, resize_mode: int = 0, denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs):
def __init__(self, init_images: list = None, resize_mode: int = 0, resize_name: str = 'None', denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs):
super().__init__(**kwargs)
self.init_images = init_images
self.resize_mode: int = resize_mode
self.resize_name: str = resize_name
self.denoising_strength: float = denoising_strength
self.image_cfg_scale: float = image_cfg_scale
self.init_latent = None
@@ -1264,11 +1266,11 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
x1, y1, x2, y2 = crop_region
mask = mask.crop(crop_region)
if mask.width != self.width or mask.height != self.height:
image_mask = images.resize_image(3, mask, self.width, self.height)
image_mask = images.resize_image(3, mask, self.width, self.height, self.resize_name)
self.paste_to = (x1, y1, x2-x1, y2-y1)
else:
if image_mask.width != self.width or image_mask.height != self.height:
image_mask = images.resize_image(self.resize_mode, image_mask, self.width, self.height)
image_mask = images.resize_image(self.resize_mode, image_mask, self.width, self.height, self.resize_name)
np_mask = np.array(image_mask)
np_mask = np.clip((np_mask.astype(np.float32)) * 2, 0, 255).astype(np.uint8)
self.mask_for_overlay = Image.fromarray(np_mask)
@@ -1280,7 +1282,13 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.color_corrections = []
imgs = []
unprocessed = []
if getattr(self, 'init_images', None) is None:
return
# raise RuntimeError("No images provided")
for img in self.init_images:
if img is None:
shared.log.warning(f"Skipping empty image: images={self.init_images}")
continue
self.init_img_hash = hashlib.sha256(img.tobytes()).hexdigest()[0:8] # pylint: disable=attribute-defined-outside-init
self.init_img_width = img.width # pylint: disable=attribute-defined-outside-init
self.init_img_height = img.height # pylint: disable=attribute-defined-outside-init
@@ -1289,7 +1297,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
image = images.flatten(img, shared.opts.img2img_background_color)
if crop_region is None and self.resize_mode != 4:
if image.width != self.width or image.height != self.height:
image = images.resize_image(self.resize_mode, image, self.width, self.height)
image = images.resize_image(self.resize_mode, image, self.width, self.height, self.resize_name)
self.width = image.width
self.height = image.height
if image_mask is not None:
@@ -1297,6 +1305,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
image_masked = Image.new('RGBa', (image.width, image.height))
image_to_paste = image.convert("RGBA").convert("RGBa")
image_to_mask = ImageOps.invert(self.mask_for_overlay.convert('L')) if self.mask_for_overlay is not None else None
image_to_mask = image_to_mask.resize((image.width, image.height), Image.Resampling.BILINEAR) if image_to_mask is not None else None
image_masked.paste(image_to_paste, mask=image_to_mask)
self.overlay_images.append(image_masked.convert('RGBA'))
except Exception as e:
@@ -1306,7 +1315,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
if crop_region is not None:
image = image.crop(crop_region)
if image.width != self.width or image.height != self.height:
image = images.resize_image(3, image, self.width, self.height)
image = images.resize_image(3, image, self.width, self.height, self.resize_name)
if image_mask is not None and self.inpainting_fill != 1:
image = modules.masking.fill(image, latent_mask)
if add_color_corrections:
@@ -1327,7 +1336,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.batch_size = len(imgs)
batch_images = np.array(imgs)
else:
raise RuntimeError(f"bad number of images passed: {len(imgs)}; expecting {self.batch_size} or less")
raise RuntimeError(f"Incorrect number of of images={len(imgs)} expected={self.batch_size} or less")
if shared.backend == shared.Backend.DIFFUSERS:
return # we've already set self.init_images and self.mask and we dont need any more processing
+2 -2
View File
@@ -23,7 +23,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
results = []
is_refiner_enabled = p.enable_hr and p.refiner_steps > 0 and p.refiner_start > 0 and p.refiner_start < 1 and shared.sd_refiner is not None
if hasattr(p, 'init_images') and len(p.init_images) > 0:
if getattr(p, 'init_images', None) is not None and len(p.init_images) > 0:
tgt_width, tgt_height = 8 * math.ceil(p.init_images[0].width / 8), 8 * math.ceil(p.init_images[0].height / 8)
if p.init_images[0].width != tgt_width or p.init_images[0].height != tgt_height:
shared.log.debug(f'Resizing init images: original={p.init_images[0].width}x{p.init_images[0].height} target={tgt_width}x{tgt_height}')
@@ -358,7 +358,7 @@ def process_diffusers(p: StableDiffusionProcessing, seeds, prompts, negative_pro
if k in possible:
args[k] = v
hypertile_set(p, hr=len(getattr(p, 'init_images', [])))
hypertile_set(p, hr=len(getattr(p, 'init_images', [])) > 0)
clean = args.copy()
clean.pop('callback', None)
clean.pop('callback_steps', None)
+8 -6
View File
@@ -74,7 +74,7 @@ def split_attention(layer: nn.Module, tile_size: int=256, min_tile_size: int=256
out = forward(x, *args[1:], **kwargs)
return out
if x.ndim == 4: # VAE
# TODO hyperlink vae breaks for diffusers when using non-standard sizes
# TODO hypertile vae breaks for diffusers when using non-standard sizes
if nh * nw > 1:
x = rearrange(x, "b c (nh h) (nw w) -> (b nh nw) c h w", nh=nh, nw=nw)
out = forward(x, *args[1:], **kwargs)
@@ -190,10 +190,12 @@ def hypertile_set(p, hr=False):
if not shared.opts.hypertile_unet_enabled:
return
error_reported = False
if not hr:
height=p.height if not hr else getattr(p, 'hr_upscale_to_y', p.height)
width=p.width if not hr else getattr(p, 'hr_upscale_to_x', p.width)
if hr:
x = getattr(p, 'hr_upscale_to_x', 0)
y = getattr(p, 'hr_upscale_to_y', 0)
width = y if y > 0 else p.width
height = x if x > 0 else p.height
else:
height=max(p.height, getattr(p, 'hr_upscale_to_y', p.height))
width=max(p.width, getattr(p, 'hr_upscale_to_x', p.width))
width=p.width
height=p.height
reset_needed = True
+2 -1
View File
@@ -63,6 +63,7 @@ restricted_opts = {
"outdir_save",
"outdir_init_images"
}
resize_modes = ["None", "Fixed", "Crop", "Fill", "Latent"]
compatibility_opts = ['clip_skip', 'uni_pc_lower_order_final', 'uni_pc_order']
console = Console(log_time=True, log_time_format='%H:%M:%S-%f')
@@ -563,7 +564,7 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), {
"postprocessing_sep_upscalers": OptionInfo("<h2>Upscaling</h2>", "", gr.HTML),
"upscaler_unload": OptionInfo(False, "Unload upscaler after processing"),
# 'upscaling_max_images_in_cache': OptionInfo(5, "Maximum number of images in upscaling cache", gr.Slider, {"minimum": 0, "maximum": 10, "step": 1, "visible": False}),
"upscaler_for_img2img": OptionInfo("None", "Default upscaler for image resize operations", gr.Dropdown, lambda: {"choices": [x.name for x in sd_upscalers]}),
"upscaler_for_img2img": OptionInfo("None", "Default upscaler for image resize operations", gr.Dropdown, lambda: {"choices": [x.name for x in sd_upscalers], "visible": False}),
"upscaler_tile_size": OptionInfo(192, "Upscaler tile size", gr.Slider, {"minimum": 0, "maximum": 512, "step": 16}),
"upscaler_tile_overlap": OptionInfo(8, "Upscaler tile overlap", gr.Slider, {"minimum": 0, "maximum": 64, "step": 1}),
}))
+16 -2
View File
@@ -8,9 +8,23 @@ from modules.ui import plaintext_to_html
debug = shared.log.debug if os.environ.get('SD_PROCESS_DEBUG', None) is not None else lambda *args, **kwargs: None
def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, latent_index: int, full_quality: bool, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, diffusers_guidance_rescale: float, clip_skip: int, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_force: bool, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, refiner_steps: int, refiner_start: int, refiner_prompt: str, refiner_negative: str, hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry, override_settings_texts, *args): # pylint: disable=unused-argument
def txt2img(id_task,
prompt, negative_prompt, prompt_styles,
steps, sampler_index, latent_index,
full_quality, restore_faces, tiling,
n_iter, batch_size,
cfg_scale, image_cfg_scale, diffusers_guidance_rescale,
clip_skip,
seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w,
height, width,
enable_hr, denoising_strength,
hr_scale, hr_upscaler, hr_force, hr_second_pass_steps, hr_resize_x, hr_resize_y,
refiner_steps, refiner_start, refiner_prompt, refiner_negative,
hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry,
override_settings_texts,
*args):
debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative_prompt={negative_prompt}|prompt_styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|latent_index={latent_index}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|n_iter={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|clip_skip={clip_skip}|seed={seed}|subseed={subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}||height={height}|width={width}|enable_hr={enable_hr}|denoising_strength={denoising_strength}|hr_scale={hr_scale}|hr_upscaler={hr_upscaler}|hr_force={hr_force}|hr_second_pass_steps={hr_second_pass_steps}|hr_resize_x={hr_resize_x}|hr_resize_y={hr_resize_y}|image_cfg_scale={image_cfg_scale}|diffusers_guidance_rescale={diffusers_guidance_rescale}|refiner_steps={refiner_steps}|refiner_start={refiner_start}|refiner_prompt={refiner_prompt}|refiner_negative={refiner_negative}|override_settings_texts={override_settings_texts}')
debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative={negative_prompt}|styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|latent_index={latent_index}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|batch_count={n_iter}|batch_size={batch_size}|cfg_scale={cfg_scale}|clip_skip={clip_skip}|seed={seed}|subseed={subseed}|subseed_strength={subseed_strength}|seed_resize_from_h={seed_resize_from_h}|seed_resize_from_w={seed_resize_from_w}|height={height}|width={width}|enable_hr={enable_hr}|denoising_strength={denoising_strength}|hr_scale={hr_scale}|hr_upscaler={hr_upscaler}|hr_force={hr_force}|hr_second_pass_steps={hr_second_pass_steps}|hr_resize_x={hr_resize_x}|hr_resize_y={hr_resize_y}|image_cfg_scale={image_cfg_scale}|diffusers_guidance_rescale={diffusers_guidance_rescale}|refiner_steps={refiner_steps}|refiner_start={refiner_start}|refiner_prompt={refiner_prompt}|refiner_negative={refiner_negative}|override_settings={override_settings_texts}')
if shared.sd_model is None:
shared.log.warning('Model not loaded')
+198 -216
View File
@@ -48,6 +48,7 @@ txt2img_paste_fields = []
img2img_paste_fields = []
txt2img_args = []
img2img_args = []
paste_function = None
if not cmd_opts.share and not cmd_opts.listen:
@@ -60,18 +61,15 @@ def gr_show(visible=True):
return {"visible": visible, "__type__": "update"}
sample_img2img = "assets/stable-samples/img2img/sketch-mountains-input.jpg"
sample_img2img = sample_img2img if os.path.exists(sample_img2img) else None
paste_function = None
def create_output_panel(tabname, outdir): # pylint: disable=unused-argument # outdir is used by extensions
a, b, c, _d, e = ui_common.create_output_panel(tabname)
return a, b, c, e
def plaintext_to_html(text): # may be referenced by extensions
return ui_common.plaintext_to_html(text)
def infotext_to_html(text): # may be referenced by extensions
return ui_common.infotext_to_html(text)
@@ -158,6 +156,16 @@ def interrogate_deepbooru(image):
return gr.update() if prompt is None else prompt
def create_batch_inputs(tab):
with gr.Accordion(open=False, label="Batch", elem_id=f"{tab}_batch", elem_classes=["small-accordion"]):
with FormRow(elem_id=f"{tab}_row_batch"):
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id=f"{tab}_batch_count")
batch_size = gr.Slider(minimum=1, maximum=32, step=1, label='Batch size', value=1, elem_id=f"{tab}_batch_size")
batch_switch_btn = ToolButton(value=symbols.switch, elem_id=f"{tab}_batch_switch_btn", label="Switch dims")
batch_switch_btn.click(lambda w, h: (h, w), inputs=[batch_count, batch_size], outputs=[batch_count, batch_size], show_progress=False)
return batch_count, batch_size
def create_seed_inputs(tab):
with gr.Accordion(open=False, label="Seed", elem_id=f"{tab}_seed_group", elem_classes=["small-accordion"]):
with FormRow(elem_id=f"{tab}_seed_row", variant="compact"):
@@ -174,14 +182,89 @@ def create_seed_inputs(tab):
seed_resize_from_h = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize seed from height", value=0, elem_id=f"{tab}_seed_resize_from_h")
random_seed.click(fn=lambda: [-1, -1], show_progress=False, inputs=[], outputs=[seed, subseed])
random_subseed.click(fn=lambda: -1, show_progress=False, inputs=[], outputs=[subseed])
return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w
return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w
def create_advanced_inputs(tab):
with gr.Accordion(open=False, label="Advanced", elem_id=f"{tab}_advanced", elem_classes=["small-accordion"]):
with gr.Group():
with FormRow():
cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='CFG scale', value=6.0, elem_id=f"{tab}_cfg_scale")
clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=14, step=1, elem_id=f"{tab}_clip_skip", interactive=True)
with FormRow():
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='Secondary CFG scale', value=6.0, elem_id=f"{tab}_image_cfg_scale")
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Guidance rescale', value=0.7, elem_id=f"{tab}_image_cfg_rescale", visible=modules.shared.backend == modules.shared.Backend.DIFFUSERS)
with gr.Group():
with FormRow():
full_quality = gr.Checkbox(label='Full quality', value=True, elem_id=f"{tab}_full_quality")
restore_faces = gr.Checkbox(label='Face restore', value=False, visible=len(modules.shared.face_restorers) > 1, elem_id=f"{tab}_restore_faces")
tiling = gr.Checkbox(label='Tiling', value=False, elem_id=f"{tab}_tiling", visible=modules.shared.backend == modules.shared.Backend.ORIGINAL)
with gr.Group(visible=modules.shared.backend == modules.shared.Backend.DIFFUSERS):
with FormRow():
hdr_clamp = gr.Checkbox(label='HDR clamp', value=False, elem_id=f"{tab}_hdr_clamp")
hdr_boundary = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=4.0, label='Range', elem_id=f"{tab}_hdr_boundary")
hdr_threshold = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, value=0.95, label='Threshold', elem_id=f"{tab}_hdr_threshold")
with FormRow():
hdr_center = gr.Checkbox(label='HDR center', value=False, elem_id=f"{tab}_hdr_center")
hdr_channel_shift = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=1.0, label='Channel shift', elem_id=f"{tab}_hdr_channel_shift")
hdr_full_shift = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=1, label='Full shift', elem_id=f"{tab}_hdr_full_shift")
with FormRow():
hdr_maximize = gr.Checkbox(label='HDR maximize', value=False, elem_id=f"{tab}_hdr_maximize")
hdr_max_center = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=0.6, label='Center', elem_id=f"{tab}_hdr_max_center")
hdr_max_boundry = gr.Slider(minimum=0.5, maximum=2.0, step=0.1, value=1.0, label='Range', elem_id=f"{tab}_hdr_max_boundry")
return cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, full_quality, restore_faces, tiling, hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry
def create_resize_inputs(tab, images):
dummy_component = gr.Number(visible=False, value=0)
with gr.Accordion(open=False, label="Resize", elem_classes=["small-accordion"], elem_id=f"{tab}_resize_group"):
with gr.Row():
resize_mode = gr.Radio(label="Resize mode", elem_id=f"{tab}_resize_mode", choices=modules.shared.resize_modes, type="index", value="None")
with gr.Row():
resize_name = gr.Dropdown(label="Resize method", elem_id=f"{tab}_resize_name", choices=[x.name for x in modules.shared.sd_upscalers], value=opts.upscaler_for_img2img)
with FormRow(visible=True) as _resize_group:
with gr.Column(elem_id=f"{tab}_column_size", scale=4):
selected_scale_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated
with gr.Tabs():
with gr.Tab(label="Resize to") as tab_scale_to:
with FormRow():
with gr.Column(elem_id=f"{tab}_column_size", scale=4):
with FormRow():
width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=512, elem_id=f"{tab}_width")
height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=512, elem_id=f"{tab}_height")
with gr.Column(elem_id=f"{tab}_column_dim", scale=1, elem_classes="dimensions-tools"):
with FormRow():
res_switch_btn = ToolButton(value=symbols.switch, elem_id=f"{tab}_res_switch_btn")
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
detect_image_size_btn = ToolButton(value=symbols.detect, elem_id=f"{tab}_detect_image_size_btn")
detect_image_size_btn.click(fn=lambda w, h, _: (w or gr.update(), h or gr.update()), _js="currentImg2imgSourceResolution", inputs=[dummy_component, dummy_component, dummy_component], outputs=[width, height], show_progress=False)
with gr.Tab(label="Resize by") as tab_scale_by:
scale_by = gr.Slider(minimum=0.05, maximum=4.0, step=0.05, label="Scale", value=1.0, elem_id=f"{tab}_scale")
with FormRow():
scale_by_html = FormHTML(resize_from_to_html(0, 0, 0.0), elem_id=f"{tab}_scale_resolution_preview")
gr.Slider(label="Unused", elem_id=f"{tab}_unused_scale_by_slider")
button_update_resize_to = gr.Button(visible=False, elem_id=f"{tab}_update_resize_to")
on_change_args = dict(fn=resize_from_to_html, _js="currentImg2imgSourceResolution", inputs=[dummy_component, dummy_component, scale_by], outputs=scale_by_html, show_progress=False)
scale_by.release(**on_change_args)
button_update_resize_to.click(**on_change_args)
for component in images:
component.change(fn=lambda: None, _js="updateImg2imgResizeToTextAfterChangingImage", inputs=[], outputs=[], show_progress=False)
tab_scale_to.select(fn=lambda: 0, inputs=[], outputs=[selected_scale_tab])
tab_scale_by.select(fn=lambda: 1, inputs=[], outputs=[selected_scale_tab])
# resize_mode.change(fn=lambda x: gr.update(visible=x != 0), inputs=[resize_mode], outputs=[_resize_group])
return resize_mode, resize_name, width, height, scale_by, selected_scale_tab
def connect_clear_prompt(button): # pylint: disable=unused-argument
pass
def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, dummy_component, is_subseed):
def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, is_subseed):
""" Connects a 'reuse (sub)seed' button's click event so that it copies last used
(sub)seed value from generation info the to the seed field. If copying subseed and subseed strength
was 0, i.e. no variation seed was used, it copies the normal seed value instead."""
@@ -202,6 +285,7 @@ def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info:
log.error(f"Error parsing JSON generation info: {gen_info_string}")
return [res, gr_show(False)]
dummy_component = gr.Number(visible=False, value=0)
reuse_seed.click(fn=copy_seed, _js="(x, y) => [x, selected_gallery_index()]", show_progress=False, inputs=[generation_info, dummy_component], outputs=[seed, dummy_component])
@@ -255,8 +339,8 @@ def create_toprow(is_img2img: bool = False, id_part: str = None):
button_deepbooru = None
if is_img2img:
with gr.Column(scale=1, elem_classes="interrogate-col"):
button_interrogate = gr.Button('Interrogate\nCLIP', elem_id="interrogate")
button_deepbooru = gr.Button('Interrogate\nDeepBooru', elem_id="deepbooru")
button_interrogate = gr.Button('Interrogate\nCLIP', elem_id=f"{id_part}_interrogate")
button_deepbooru = gr.Button('Interrogate\nDeepBooru', elem_id=f"{id_part}_deepbooru")
with gr.Column(scale=1, elem_id=f"{id_part}_actions_column"):
with gr.Row(elem_id=f"{id_part}_generate_box"):
submit = gr.Button('Generate', elem_id=f"{id_part}_generate", variant='primary')
@@ -278,14 +362,14 @@ def create_toprow(is_img2img: bool = False, id_part: str = None):
negative_token_counter = gr.HTML(value="<span>0/75</span>", elem_id=f"{id_part}_negative_token_counter", elem_classes=["token-counter"])
negative_token_button = gr.Button(visible=False, elem_id=f"{id_part}_negative_token_button")
with gr.Row(elem_id=f"{id_part}_styles_row"):
prompt_styles = gr.Dropdown(label="Styles", elem_id=f"{id_part}_styles", choices=[style.name for style in modules.shared.prompt_styles.styles.values()], value=[], multiselect=True)
prompt_styles_btn_refresh = ToolButton(symbols.refresh, elem_id=f"{id_part}_styles_refresh", visible=True)
prompt_styles_btn_refresh.click(fn=lambda: gr.update(choices=[style.name for style in modules.shared.prompt_styles.styles.values()]), inputs=[], outputs=[prompt_styles])
prompt_styles_btn_select = gr.Button('Select', elem_id=f"{id_part}_styles_select", visible=False)
prompt_styles_btn_select.click(_js="applyStyles", fn=parse_style, inputs=[prompt_styles], outputs=[prompt_styles])
prompt_styles_btn_apply = ToolButton(symbols.apply, elem_id=f"{id_part}_extra_apply", visible=False)
prompt_styles_btn_apply.click(fn=apply_styles, inputs=[prompt, negative_prompt, prompt_styles], outputs=[prompt, negative_prompt, prompt_styles])
return prompt, prompt_styles, negative_prompt, submit, button_interrogate, button_deepbooru, button_paste, button_extra, token_counter, token_button, negative_token_counter, negative_token_button
styles = gr.Dropdown(label="Styles", elem_id=f"{id_part}_styles", choices=[style.name for style in modules.shared.prompt_styles.styles.values()], value=[], multiselect=True)
styles_btn_refresh = ToolButton(symbols.refresh, elem_id=f"{id_part}_styles_refresh", visible=True)
styles_btn_refresh.click(fn=lambda: gr.update(choices=[style.name for style in modules.shared.prompt_styles.styles.values()]), inputs=[], outputs=[styles])
styles_btn_select = gr.Button('Select', elem_id=f"{id_part}_styles_select", visible=False)
styles_btn_select.click(_js="applyStyles", fn=parse_style, inputs=[styles], outputs=[styles])
styles_btn_apply = ToolButton(symbols.apply, elem_id=f"{id_part}_extra_apply", visible=False)
styles_btn_apply.click(fn=apply_styles, inputs=[prompt, negative_prompt, styles], outputs=[prompt, negative_prompt, styles])
return prompt, styles, negative_prompt, submit, button_interrogate, button_deepbooru, button_paste, button_extra, token_counter, token_button, negative_token_counter, negative_token_button
def setup_progressbar(*args, **kwargs): # pylint: disable=unused-argument
@@ -362,6 +446,44 @@ def create_sampler_and_steps_selection(choices, tabname):
return steps, sampler_index
def create_sampler_inputs(tab):
with gr.Accordion(open=False, label="Sampler", elem_id=f"{tab}_sampler", elem_classes=["small-accordion"]):
with FormRow(elem_id=f"{tab}_row_sampler"):
modules.sd_samplers.set_samplers()
steps, sampler_index = create_sampler_and_steps_selection(modules.sd_samplers.samplers, tab)
return steps, sampler_index
def create_hires_inputs(tab):
with gr.Accordion(open=False, label="Second pass", elem_id=f"{tab}_second_pass", elem_classes=["small-accordion"]):
with FormGroup():
with FormRow(elem_id=f"{tab}_hires_row1"):
enable_hr = gr.Checkbox(label='Enable second pass', value=False, elem_id=f"{tab}_enable_hr")
with FormRow(elem_id=f"{tab}_hires_row2"):
latent_index = gr.Dropdown(label='Secondary sampler', elem_id=f"{tab}_sampling_alt", choices=[x.name for x in modules.sd_samplers.samplers], value='Default', type="index")
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Denoising strength', value=0.5, elem_id=f"{tab}_denoising_strength")
with FormRow(elem_id=f"{tab}_hires_finalres", variant="compact"):
hr_final_resolution = FormHTML(value="", elem_id=f"{tab}_hr_finalres", label="Upscaled resolution", interactive=False)
with FormRow(elem_id=f"{tab}_hires_fix_row1", variant="compact"):
hr_upscaler = gr.Dropdown(label="Upscaler", elem_id=f"{tab}_hr_upscaler", choices=[*modules.shared.latent_upscale_modes, *[x.name for x in modules.shared.sd_upscalers]], value=modules.shared.latent_upscale_default_mode)
hr_force = gr.Checkbox(label='Force Hires', value=False, elem_id=f"{tab}_hr_force")
with FormRow(elem_id=f"{tab}_hires_fix_row2", variant="compact"):
hr_second_pass_steps = gr.Slider(minimum=0, maximum=99, step=1, label='Hires steps', elem_id=f"{tab}_steps_alt", value=20)
hr_scale = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Upscale by", value=2.0, elem_id=f"{tab}_hr_scale")
with FormRow(elem_id=f"{tab}_hires_fix_row3", variant="compact"):
hr_resize_x = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize width to", value=0, elem_id=f"{tab}_hr_resize_x")
hr_resize_y = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize height to", value=0, elem_id=f"{tab}_hr_resize_y")
with FormGroup(visible=modules.shared.backend == modules.shared.Backend.DIFFUSERS):
with FormRow(elem_id=f"{tab}_refiner_row1", variant="compact"):
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Refiner start', value=0.8, elem_id=f"{tab}_refiner_start")
refiner_steps = gr.Slider(minimum=0, maximum=99, step=1, label="Refiner steps", elem_id=f"{tab}_refiner_steps", value=5)
with FormRow(elem_id=f"{tab}_refiner_row3", variant="compact"):
refiner_prompt = gr.Textbox(value='', label='Secondary Prompt', elem_id=f"{tab}_refiner_prompt")
with FormRow(elem_id="txt2img_refiner_row4", variant="compact"):
refiner_negative = gr.Textbox(value='', label='Secondary negative prompt', elem_id=f"{tab}_refiner_neg_prompt")
return enable_hr, latent_index, denoising_strength, hr_final_resolution, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative
def get_value_for_setting(key):
value = getattr(opts, key)
info = opts.data_labels[key]
@@ -371,13 +493,14 @@ def get_value_for_setting(key):
def ordered_ui_categories():
return ['dimensions', 'sampler', 'seed', 'denoising', 'cfg', 'checkboxes', 'accordions', 'override_settings', 'scripts'] # TODO: a1111 compatibility item, not implemented
return ['dimensions', 'sampler', 'seed', 'denoising', 'cfg', 'checkboxes', 'accordions', 'override_settings', 'scripts'] # a1111 compatibility item, not implemented
def create_override_settings_dropdown(tabname, row): # pylint: disable=unused-argument
dropdown = gr.Dropdown([], label="Override settings", visible=False, elem_id=f"{tabname}_override_settings", multiselect=True)
dropdown.change(fn=lambda x: gr.Dropdown.update(visible=len(x) > 0), inputs=[dropdown], outputs=[dropdown])
return dropdown
def create_override_inputs(tab): # pylint: disable=unused-argument
with FormRow(elem_id=f"{tab}_override_settings_row"):
override_settings = gr.Dropdown([], value=None, label="Override settings", visible=False, elem_id=f"{tab}_override_settings", multiselect=True)
override_settings.change(fn=lambda x: gr.Dropdown.update(visible=len(x) > 0), inputs=[override_settings], outputs=[override_settings])
return override_settings
def create_ui(startup_timer = None):
@@ -390,12 +513,14 @@ def create_ui(startup_timer = None):
modules.scripts.scripts_current = modules.scripts.scripts_txt2img
modules.scripts.scripts_txt2img.initialize_scripts(is_img2img=False)
with gr.Blocks(analytics_enabled=False) as txt2img_interface:
txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, submit, _interrogate, _deepbooru, txt2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=False)
dummy_component = gr.Label(visible=False)
txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, txt2img_submit, _interrogate, _deepbooru, txt2img_paste, txt2img_extra_networks_button, txt2img_token_counter, txt2img_token_button, txt2img_negative_token_counter, txt2img_negative_token_button = create_toprow(is_img2img=False, id_part="txt2img")
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False)
txt_prompt_img.change(fn=modules.images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img])
with FormRow(variant='compact', elem_id="txt2img_extra_networks", visible=False) as extra_networks_ui:
from modules import ui_extra_networks
extra_networks_ui = ui_extra_networks.create_ui(extra_networks_ui, extra_networks_button, 'txt2img', skip_indexing=opts.extra_network_skip_indexing)
extra_networks_ui = ui_extra_networks.create_ui(extra_networks_ui, txt2img_extra_networks_button, 'txt2img', skip_indexing=opts.extra_network_skip_indexing)
timer.startup.record('ui-extra-networks')
with gr.Row(elem_id="txt2img_interface", equal_height=False):
@@ -405,79 +530,18 @@ def create_ui(startup_timer = None):
width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=512, elem_id="txt2img_width")
height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=512, elem_id="txt2img_height")
res_switch_btn = ToolButton(value=symbols.switch, elem_id="txt2img_res_switch_btn", label="Switch dims")
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
with FormGroup(elem_classes="settings-accordion"):
with gr.Accordion(open=False, label="Sampler", elem_id="txt2img_sampler", elem_classes=["small-accordion"]):
with FormRow(elem_id="txt2img_row_sampler"):
modules.sd_samplers.set_samplers()
steps, sampler_index = create_sampler_and_steps_selection(modules.sd_samplers.samplers, "txt2img")
with gr.Accordion(open=False, label="Batch", elem_id="txt2img_batch", elem_classes=["small-accordion"]):
with FormRow(elem_id="txt2img_row_batch"):
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="txt2img_batch_count")
batch_size = gr.Slider(minimum=1, maximum=32, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size")
batch_switch_btn = ToolButton(value=symbols.switch, elem_id="txt2img_batch_switch_btn", label="Switch dims")
steps, sampler_index = create_sampler_inputs('txt2img')
batch_count, batch_size = create_batch_inputs('txt2img')
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w = create_seed_inputs('txt2img')
cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, full_quality, restore_faces, tiling, hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry = create_advanced_inputs('txt2img')
enable_hr, latent_index, denoising_strength, hr_final_resolution, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = create_hires_inputs('txt2img')
override_settings = create_override_inputs('txt2img')
with gr.Accordion(open=False, label="Advanced", elem_id="txt2img_advanced", elem_classes=["small-accordion"]):
with gr.Group():
with FormRow():
cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='CFG scale', value=6.0, elem_id="txt2img_cfg_scale")
clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=14, step=1, elem_id='txt2img_clip_skip', interactive=True)
with FormRow():
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='Secondary CFG scale', value=6.0, elem_id="txt2img_image_cfg_scale")
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Guidance rescale', value=0.7, elem_id="txt2img_image_cfg_rescale")
with gr.Group():
with FormRow():
full_quality = gr.Checkbox(label='Full quality', value=True, elem_id="txt2img_full_quality")
restore_faces = gr.Checkbox(label='Face restore', value=False, visible=len(modules.shared.face_restorers) > 1, elem_id="txt2img_restore_faces")
tiling = gr.Checkbox(label='Tiling', value=False, elem_id="txt2img_tiling")
with gr.Group():
with FormRow():
hdr_clamp = gr.Checkbox(label='HDR clamp', value=False, elem_id="txt2img_hdr_clamp")
hdr_boundary = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=4.0, label='Range', elem_id="txt2img_hdr_boundary")
hdr_threshold = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, value=0.95, label='Threshold', elem_id="txt2img_hdr_threshold")
with FormRow():
hdr_center = gr.Checkbox(label='HDR center', value=False, elem_id="txt2img_hdr_center")
hdr_channel_shift = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=1.0, label='Channel shift', elem_id="txt2img_hdr_channel_shift")
hdr_full_shift = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=1, label='Full shift', elem_id="txt2img_hdr_full_shift")
with FormRow():
hdr_maximize = gr.Checkbox(label='HDR maximize', value=False, elem_id="txt2img_hdr_maximize")
hdr_max_center = gr.Slider(minimum=0.0, maximum=2.0, step=0.1, value=0.6, label='Center', elem_id="txt2img_hdr_max_center")
hdr_max_boundry = gr.Slider(minimum=0.5, maximum=2.0, step=0.1, value=1.0, label='Range', elem_id="txt2img_hdr_max_boundry")
with gr.Accordion(open=False, label="Second pass", elem_id="txt2img_second_pass", elem_classes=["small-accordion"]):
with FormGroup():
with FormRow(elem_id="sampler_selection_txt2img_alt_row1"):
enable_hr = gr.Checkbox(label='Enable second pass', value=False, elem_id="txt2img_enable_hr")
with FormRow(elem_id="sampler_selection_txt2img_alt_row1"):
latent_index = gr.Dropdown(label='Secondary sampler', elem_id="txt2img_sampling_alt", choices=[x.name for x in modules.sd_samplers.samplers], value='Default', type="index")
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Denoising strength', value=0.5, elem_id="txt2img_denoising_strength")
with FormRow(elem_id="txt2img_hires_finalres", variant="compact"):
hr_final_resolution = FormHTML(value="", elem_id="txtimg_hr_finalres", label="Upscaled resolution", interactive=False)
with FormRow(elem_id="txt2img_hires_fix_row1", variant="compact"):
hr_upscaler = gr.Dropdown(label="Upscaler", elem_id="txt2img_hr_upscaler", choices=[*modules.shared.latent_upscale_modes, *[x.name for x in modules.shared.sd_upscalers]], value=modules.shared.latent_upscale_default_mode)
hr_force = gr.Checkbox(label='Force Hires', value=False, elem_id="txt2img_hr_force")
with FormRow(elem_id="txt2img_hires_fix_row2", variant="compact"):
hr_second_pass_steps = gr.Slider(minimum=0, maximum=99, step=1, label='Hires steps', elem_id="txt2img_steps_alt", value=20)
hr_scale = gr.Slider(minimum=1.0, maximum=4.0, step=0.05, label="Upscale by", value=2.0, elem_id="txt2img_hr_scale")
with FormRow(elem_id="txt2img_hires_fix_row3", variant="compact"):
hr_resize_x = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize width to", value=0, elem_id="txt2img_hr_resize_x")
hr_resize_y = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize height to", value=0, elem_id="txt2img_hr_resize_y")
with FormGroup(visible=modules.shared.backend == modules.shared.Backend.DIFFUSERS):
with FormRow(elem_id="txt2img_refiner_row1", variant="compact"):
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Refiner start', value=0.8, elem_id="txt2img_refiner_start")
refiner_steps = gr.Slider(minimum=0, maximum=99, step=1, label="Refiner steps", elem_id="txt2img_refiner_steps", value=5)
with FormRow(elem_id="txt2img_refiner_row3", variant="compact"):
refiner_prompt = gr.Textbox(value='', label='Secondary Prompt')
with FormRow(elem_id="txt2img_refiner_row4", variant="compact"):
refiner_negative = gr.Textbox(value='', label='Secondary negative prompt')
with FormRow(elem_id="txt2img_override_settings_row") as row:
override_settings = create_override_settings_dropdown('txt2img', row)
custom_inputs = modules.scripts.scripts_txt2img.setup_ui()
txt2img_script_inputs = modules.scripts.scripts_txt2img.setup_ui()
hr_resolution_preview_inputs = [width, height, hr_scale, hr_resize_x, hr_resize_y, hr_upscaler]
for preview_input in hr_resolution_preview_inputs:
@@ -489,21 +553,19 @@ def create_ui(startup_timer = None):
show_progress=False,
)
txt2img_gallery, generation_info, html_info, _html_info_formatted, html_log = ui_common.create_output_panel("txt2img")
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)
txt2img_gallery, txt2img_generation_info, txt2img_html_info, _txt2img_html_info_formatted, txt2img_html_log = ui_common.create_output_panel("txt2img")
connect_reuse_seed(seed, reuse_seed, txt2img_generation_info, is_subseed=False)
connect_reuse_seed(subseed, reuse_subseed, txt2img_generation_info, is_subseed=True)
global txt2img_args # pylint: disable=global-statement
dummy_component = gr.Textbox(visible=False, value='dummy')
txt2img_args = [
dummy_component,
txt2img_prompt, txt2img_negative_prompt,
txt2img_prompt_styles,
steps,
sampler_index, latent_index,
txt2img_prompt, txt2img_negative_prompt, txt2img_prompt_styles,
steps, sampler_index, latent_index,
full_quality, restore_faces, tiling,
batch_count, batch_size,
cfg_scale, image_cfg_scale,
diffusers_guidance_rescale,
cfg_scale, image_cfg_scale, diffusers_guidance_rescale,
clip_skip,
seed, subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w,
height, width,
@@ -516,21 +578,17 @@ def create_ui(startup_timer = None):
txt2img_dict = dict(
fn=wrap_gradio_gpu_call(modules.txt2img.txt2img, extra_outputs=[None, '', '']),
_js="submit_txt2img",
inputs=txt2img_args + custom_inputs,
inputs=txt2img_args + txt2img_script_inputs,
outputs=[
txt2img_gallery,
generation_info,
html_info,
html_log,
txt2img_generation_info,
txt2img_html_info,
txt2img_html_log,
],
show_progress=False,
)
txt2img_prompt.submit(**txt2img_dict)
submit.click(**txt2img_dict)
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
batch_switch_btn.click(lambda w, h: (h, w), inputs=[batch_count, batch_size], outputs=[batch_count, batch_size], show_progress=False)
txt_prompt_img.change(fn=modules.images.image_data, inputs=[txt_prompt_img], outputs=[txt2img_prompt, txt_prompt_img])
txt2img_submit.click(**txt2img_dict)
global txt2img_paste_fields # pylint: disable=global-statement
txt2img_paste_fields = [
@@ -581,8 +639,8 @@ def create_ui(startup_timer = None):
parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields, override_settings)
parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=txt2img_paste, tabname="txt2img", source_text_component=txt2img_prompt, source_image_component=None))
token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_prompt, steps], outputs=[token_counter])
negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_negative_prompt, steps], outputs=[negative_token_counter])
txt2img_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_prompt, steps], outputs=[txt2img_token_counter])
txt2img_negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_negative_prompt, steps], outputs=[txt2img_negative_token_counter])
ui_extra_networks.setup_ui(extra_networks_ui, txt2img_gallery)
@@ -592,12 +650,12 @@ def create_ui(startup_timer = None):
modules.scripts.scripts_current = modules.scripts.scripts_img2img
modules.scripts.scripts_img2img.initialize_scripts(is_img2img=True)
with gr.Blocks(analytics_enabled=False) as img2img_interface:
img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, submit, img2img_interrogate, img2img_deepbooru, img2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=True)
img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, submit, img2img_interrogate, img2img_deepbooru, img2img_paste, img2img_extra_networks_button, img2img_token_counter, img2img_token_button, img2img_negative_token_counter, img2img_negative_token_button = create_toprow(is_img2img=True, id_part="img2img")
img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="binary", visible=False)
with FormRow(variant='compact', elem_id="img2img_extra_networks", visible=False) as extra_networks_ui:
from modules import ui_extra_networks
extra_networks_ui_img2img = ui_extra_networks.create_ui(extra_networks_ui, extra_networks_button, 'img2img', skip_indexing=opts.extra_network_skip_indexing)
extra_networks_ui_img2img = ui_extra_networks.create_ui(extra_networks_ui, img2img_extra_networks_button, 'img2img', skip_indexing=opts.extra_network_skip_indexing)
with FormRow(elem_id="img2img_interface", equal_height=False):
with gr.Column(variant='compact', elem_id="img2img_settings"):
@@ -671,78 +729,18 @@ def create_ui(startup_timer = None):
button.click(fn=lambda: None, _js=f"switch_to_{name.replace(' ', '_')}", inputs=[], outputs=[])
with FormGroup(elem_classes="settings-accordion"):
with gr.Accordion(open=False, label="Sampler", elem_classes=["small-accordion"], elem_id="img2img_sampling_group"):
modules.sd_samplers.set_samplers()
steps, sampler_index = create_sampler_and_steps_selection(modules.sd_samplers.samplers_for_img2img, "img2img")
with gr.Accordion(open=False, label="Resize", elem_classes=["small-accordion"], elem_id="img2img_resize_group"):
with gr.Row():
resize_mode = gr.Radio(label="Resize mode", elem_id="resize_mode", choices=["None", "Resize fixed", "Crop and resize", "Resize and fill", "Latent upscale"], type="index", value="None")
with FormRow():
with gr.Column(elem_id="img2img_column_size", scale=4):
selected_scale_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated
with gr.Tabs():
with gr.Tab(label="Resize to") as tab_scale_to:
with FormRow():
with gr.Column(elem_id="img2img_column_size", scale=4):
with FormRow():
width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=512, elem_id="img2img_width")
height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=512, elem_id="img2img_height")
with gr.Column(elem_id="img2img_column_dim", scale=1, elem_classes="dimensions-tools"):
with FormRow():
res_switch_btn = ToolButton(value=symbols.switch, elem_id="img2img_res_switch_btn")
detect_image_size_btn = ToolButton(value=symbols.detect, elem_id="img2img_detect_image_size_btn")
with gr.Tab(label="Resize by") as tab_scale_by:
scale_by = gr.Slider(minimum=0.05, maximum=4.0, step=0.05, label="Scale", value=1.0, elem_id="img2img_scale")
with FormRow():
scale_by_html = FormHTML(resize_from_to_html(0, 0, 0.0), elem_id="img2img_scale_resolution_preview")
gr.Slider(label="Unused", elem_id="img2img_unused_scale_by_slider")
button_update_resize_to = gr.Button(visible=False, elem_id="img2img_update_resize_to")
on_change_args = dict(
fn=resize_from_to_html,
_js="currentImg2imgSourceResolution",
inputs=[dummy_component, dummy_component, scale_by],
outputs=scale_by_html,
show_progress=False,
)
scale_by.release(**on_change_args)
button_update_resize_to.click(**on_change_args)
for component in [init_img, sketch]:
component.change(fn=lambda: None, _js="updateImg2imgResizeToTextAfterChangingImage", inputs=[], outputs=[], show_progress=False)
tab_scale_to.select(fn=lambda: 0, inputs=[], outputs=[selected_scale_tab])
tab_scale_by.select(fn=lambda: 1, inputs=[], outputs=[selected_scale_tab])
with gr.Accordion(open=False, label="Batch", elem_classes=["small-accordion"], elem_id="img2img_batch_group"):
with FormRow(elem_id="img2img_column_batch"):
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="img2img_batch_size")
steps, sampler_index = create_sampler_inputs('img2img')
resize_mode, resize_name, width, height, scale_by, selected_scale_tab = create_resize_inputs('img2img', [init_img, sketch])
batch_count, batch_size = create_batch_inputs('img2img')
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w = create_seed_inputs('img2img')
with gr.Accordion(open=False, label="Denoise", elem_classes=["small-accordion"], elem_id="img2img_denoise_group"):
with FormRow():
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Denoising strength', value=0.50, elem_id="img2img_denoising_strength")
refiner_start = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Denoise start', value=0.0, elem_id="img2img_refiner_start")
with gr.Accordion(open=False, label="Advanced", elem_classes=["small-accordion"], elem_id="img2img_advanced_group"):
with FormRow():
cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.1, label='CFG scale', value=6.0, elem_id="img2img_cfg_scale")
image_cfg_scale = gr.Slider(minimum=0.0, maximum=30.0, step=0.15, label='Image CFG scale', value=1.5, elem_id="img2img_image_cfg_scale")
with FormRow():
clip_skip = gr.Slider(label='CLIP skip', value=1, minimum=1, maximum=4, step=1, elem_id='img2img_clip_skip', interactive=True)
diffusers_guidance_rescale = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label='Guidance rescale', value=0.7, elem_id="txt2img_image_cfg_rescale")
with FormRow(elem_classes="img2img_checkboxes_row", variant="compact"):
full_quality = gr.Checkbox(label='Full quality', value=True, elem_id="img2img_full_quality")
restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(modules.shared.face_restorers) > 1, elem_id="img2img_restore_faces")
tiling = gr.Checkbox(label='Tiling', value=False, elem_id="img2img_tiling")
cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, full_quality, restore_faces, tiling, hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry = create_advanced_inputs('img2img')
with FormGroup(elem_id="inpaint_controls", visible=False) as inpaint_controls:
with FormRow():
@@ -765,32 +763,23 @@ def create_ui(startup_timer = None):
for i, elem in enumerate(img2img_tabs):
elem.select(fn=lambda tab=i: select_img2img_tab(tab), inputs=[], outputs=[inpaint_controls, mask_alpha]) # pylint: disable=cell-var-from-loop
with FormRow(elem_id="img2img_override_settings_row") as row:
override_settings = create_override_settings_dropdown('img2img', row)
override_settings = create_override_inputs('img2img')
with FormGroup(elem_id="img2img_script_container"):
custom_inputs = modules.scripts.scripts_img2img.setup_ui()
img2img_script_inputs = modules.scripts.scripts_img2img.setup_ui()
img2img_gallery, generation_info, html_info, _html_info_formatted, html_log = ui_common.create_output_panel("img2img")
img2img_gallery, img2img_generation_info, img2img_html_info, _img2img_html_info_formatted, img2img_html_log = ui_common.create_output_panel("img2img")
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)
connect_reuse_seed(seed, reuse_seed, img2img_generation_info, is_subseed=False)
connect_reuse_seed(subseed, reuse_subseed, img2img_generation_info, is_subseed=True)
img2img_prompt_img.change(
fn=modules.images.image_data,
inputs=[
img2img_prompt_img
],
outputs=[
img2img_prompt,
img2img_prompt_img
]
)
img2img_prompt_img.change(fn=modules.images.image_data, inputs=[img2img_prompt_img], outputs=[img2img_prompt, img2img_prompt_img])
dummy_component1 = gr.Textbox(visible=False, value='dummy')
dummy_component2 = gr.Number(visible=False, value=0)
global img2img_args # pylint: disable=global-statement
img2img_args = [
dummy_component, dummy_component,
img2img_prompt, img2img_negative_prompt,
img2img_prompt_styles,
dummy_component1, dummy_component2,
img2img_prompt, img2img_negative_prompt, img2img_prompt_styles,
init_img,
sketch,
init_img_with_mask,
@@ -814,25 +803,27 @@ def create_ui(startup_timer = None):
selected_scale_tab,
height, width,
scale_by,
resize_mode,
resize_mode, resize_name,
inpaint_full_res, inpaint_full_res_padding, inpainting_mask_invert,
img2img_batch_files, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir,
hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry,
override_settings,
]
img2img_dict = dict(
fn=wrap_gradio_gpu_call(modules.img2img.img2img, extra_outputs=[None, '', '']),
_js="submit_img2img",
inputs= img2img_args + custom_inputs,
inputs= img2img_args + img2img_script_inputs,
outputs=[
img2img_gallery,
generation_info,
html_info,
html_log,
img2img_generation_info,
img2img_html_info,
img2img_html_log,
],
show_progress=False,
)
img2img_prompt.submit(**img2img_dict)
submit.click(**img2img_dict)
dummy_component = gr.Textbox(visible=False, value='dummy')
interrogate_args = dict(
_js="get_img2img_tab_index",
@@ -852,18 +843,8 @@ def create_ui(startup_timer = None):
img2img_interrogate.click(fn=lambda *args: process_interrogate(interrogate, *args), **interrogate_args)
img2img_deepbooru.click(fn=lambda *args: process_interrogate(interrogate_deepbooru, *args), **interrogate_args)
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
detect_image_size_btn.click(
fn=lambda w, h, _: (w or gr.update(), h or gr.update()),
_js="currentImg2imgSourceResolution",
inputs=[dummy_component, dummy_component, dummy_component],
outputs=[width, height],
show_progress=False,
)
token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_prompt, steps], outputs=[token_counter])
negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_negative_prompt, steps], outputs=[negative_token_counter])
img2img_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_prompt, steps], outputs=[img2img_token_counter])
img2img_negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_negative_prompt, steps], outputs=[img2img_negative_token_counter])
ui_extra_networks.setup_ui(extra_networks_ui_img2img, img2img_gallery)
global img2img_paste_fields # pylint: disable=global-statement
@@ -999,6 +980,7 @@ def create_ui(startup_timer = None):
components = []
component_dict = {}
modules.shared.settings_components = component_dict
dummy_component1 = gr.Label(visible=False)
script_callbacks.ui_settings_callback()
opts.reorder()
+1 -2
View File
@@ -266,8 +266,7 @@ def start_ui():
favicon_path='html/logo.ico',
allowed_paths=[os.path.dirname(__file__), cmd_opts.data_dir],
app_kwargs=fastapi_args,
# Workaround for issues with Gradio Network check timeouts (edge-case, but no other workound)
_frontend=not os.environ.get('SD_DISABLE_GRADIO_FRONTEND_CHECK', None),
_frontend=not cmd_opts.share,
)
if cmd_opts.data_dir is not None:
ui_tempdir.register_tmp_file(shared.demo, os.path.join(cmd_opts.data_dir, 'x'))