diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2447b0f..0500b3e0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,7 @@ Plus tons of minor items and fixes - see [changelog](https://github.com/vladmand ui result is always 8bit/channel hdr-effect image plus grid of original images used to create hdr grid image can be disabled via settings -> user interface -> show grid actual full-hdr image is not displayed in ui, only optionally saved to disk +- **hires** workflow now allows for full resize options, not just limited width/height/scale - **taesd** configurable number of layers can be used to speed-up taesd decoding by reducing number of ops e.g. if generating 1024px image, reducing layers by 1 will result in preview being 512px @@ -98,6 +99,7 @@ Plus tons of minor items and fixes - see [changelog](https://github.com/vladmand - **xhinker** prompt parser handle offloaded models - **control** better handle offloading - **control** upscale will use resize-to if set to non-zero values over resize-by +- **networks** add option `extra_networks_fetch` to choose if mouse-over on network should attempt to fetch additional info - speed up some garbage collection ops - sampler settings add **dynamic shift** used by flow-matching samplers to adjust between structure and details diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index e0294b4f4..ab818a8d1 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -421,21 +421,23 @@ function setupExtraNetworksForTab(tabname) { // card hover let hoverTimer = null; let previousCard = null; - gradioApp().getElementById(`${tabname}_extra_tabs`).onmouseover = (e) => { - const el = e.target.closest('.card'); // bubble-up to card - if (!el || (el.title === previousCard)) return; - if (!hoverTimer) { - hoverTimer = setTimeout(() => { - readCardDescription(el.dataset.page, el.dataset.name); - readCardTags(el, el.dataset.tags); - previousCard = el.title; - }, 300); - } - el.onmouseout = () => { - clearTimeout(hoverTimer); - hoverTimer = null; + if (window.opts.extra_networks_fetch) { + gradioApp().getElementById(`${tabname}_extra_tabs`).onmouseover = async (e) => { + const el = e.target.closest('.card'); // bubble-up to card + if (!el || (el.title === previousCard)) return; + if (!hoverTimer) { + hoverTimer = setTimeout(() => { + readCardDescription(el.dataset.page, el.dataset.name); + readCardTags(el, el.dataset.tags); + previousCard = el.title; + }, 300); + } + el.onmouseout = () => { + clearTimeout(hoverTimer); + hoverTimer = null; + }; }; - }; + } // en style if (!en) return; diff --git a/javascript/startup.js b/javascript/startup.js index f1a44faf5..245a3eae8 100644 --- a/javascript/startup.js +++ b/javascript/startup.js @@ -17,7 +17,6 @@ async function initStartup() { initImageViewer(); initGallery(); setupControlUI(); - setupExtraNetworks(); // reconnect server session await reconnectUI(); @@ -25,6 +24,7 @@ async function initStartup() { // make sure all of the ui is ready and options are loaded while (Object.keys(window.opts).length === 0) await sleep(50); executeCallbacks(uiReadyCallbacks); + setupExtraNetworks(); // optinally wait for modern ui if (window.waitForUiReady) await waitForUiReady(); diff --git a/modules/control/run.py b/modules/control/run.py index 03e4bb0ae..5b8a4bf36 100644 --- a/modules/control/run.py +++ b/modules/control/run.py @@ -66,7 +66,7 @@ def control_run(units: List[unit.Unit] = [], inputs: List[Image.Image] = [], ini resize_mode_after: int = 0, resize_name_after: str = 'None', resize_context_after: str = 'None', width_after: int = 0, height_after: int = 0, scale_by_after: float = 1.0, selected_scale_tab_after: int = 0, resize_mode_mask: int = 0, resize_name_mask: str = 'None', resize_context_mask: str = 'None', width_mask: int = 0, height_mask: int = 0, scale_by_mask: float = 1.0, selected_scale_tab_mask: int = 0, denoising_strength: float = 0, batch_count: int = 1, batch_size: int = 1, - enable_hr: bool = False, hr_sampler_index: int = None, hr_denoising_strength: float = 0.3, hr_upscaler: str = None, hr_force: bool = False, hr_second_pass_steps: int = 20, + enable_hr: bool = False, hr_sampler_index: int = None, hr_denoising_strength: float = 0.3, hr_resize_mode: int = 0, hr_resize_context: str = 'None', hr_upscaler: str = None, hr_force: bool = False, hr_second_pass_steps: int = 20, hr_scale: float = 1.0, hr_resize_x: int = 0, hr_resize_y: int = 0, refiner_steps: int = 5, refiner_start: float = 0.0, refiner_prompt: str = '', refiner_negative: str = '', video_skip_frames: int = 0, video_type: str = 'None', video_duration: float = 2.0, video_loop: bool = False, video_pad: int = 0, video_interpolate: int = 0, *input_script_args @@ -180,6 +180,8 @@ def control_run(units: List[unit.Unit] = [], inputs: List[Image.Image] = [], ini p.enable_hr = enable_hr p.hr_sampler_name = processing.get_sampler_name(hr_sampler_index) p.hr_denoising_strength = hr_denoising_strength + p.hr_resize_mode = hr_resize_mode + p.hr_resize_context = hr_resize_context p.hr_upscaler = hr_upscaler p.hr_force = hr_force p.hr_second_pass_steps = hr_second_pass_steps diff --git a/modules/images.py b/modules/images.py index 7c27ca4a4..4f42f276e 100644 --- a/modules/images.py +++ b/modules/images.py @@ -338,7 +338,7 @@ def resize_image(resize_mode, im, width, height, upscaler_name=None, output_type res = im.copy() shared.log.error(f'Invalid resize mode: {resize_mode}') t1 = time.time() - shared.log.debug(f'Image resize: input={im} width={width} height={height} mode="{shared.resize_modes[resize_mode]}" upscaler="{upscaler_name}" context="{context}" type={output_type} time={t1-t0:.2f} fn={sys._getframe(1).f_code.co_name}') # pylint: disable=protected-access + shared.log.debug(f'Image resize: input={im} width={width} height={height} mode="{shared.resize_modes[resize_mode]}" upscaler="{upscaler_name}" context="{context}" type={output_type} result={res} time={t1-t0:.2f} fn={sys._getframe(1).f_code.co_name}') # pylint: disable=protected-access return np.array(res) if output_type == 'np' else res diff --git a/modules/processing.py b/modules/processing.py index da62de1c9..9cca323a4 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -36,21 +36,21 @@ images_tensor_to_samples = processing_helpers.images_tensor_to_samples class Processed: def __init__(self, p: StableDiffusionProcessing, images_list, seed=-1, info="", subseed=None, all_prompts=None, all_negative_prompts=None, all_seeds=None, all_subseeds=None, index_of_first_image=0, infotexts=None, comments=""): self.images = images_list - self.prompt = p.prompt - self.negative_prompt = p.negative_prompt + self.prompt = p.prompt or '' + self.negative_prompt = p.negative_prompt or '' self.seed = seed if seed != -1 else p.seed self.subseed = subseed self.subseed_strength = p.subseed_strength self.info = info - self.comments = comments + self.comments = comments or '' self.width = p.width if hasattr(p, 'width') else (self.images[0].width if len(self.images) > 0 else 0) self.height = p.height if hasattr(p, 'height') else (self.images[0].height if len(self.images) > 0 else 0) - self.sampler_name = p.sampler_name - self.cfg_scale = p.cfg_scale - self.image_cfg_scale = p.image_cfg_scale - self.steps = p.steps - self.batch_size = p.batch_size - self.restore_faces = p.restore_faces + self.sampler_name = p.sampler_name or '' + self.cfg_scale = p.cfg_scale or 0 + self.image_cfg_scale = p.image_cfg_scale or 0 + self.steps = p.steps or 0 + self.batch_size = max(1, p.batch_size) + self.restore_faces = p.restore_faces or False self.face_restoration_model = shared.opts.face_restoration_model if p.restore_faces else None self.sd_model_hash = getattr(shared.sd_model, 'sd_model_hash', '') if model_data.sd_model is not None else '' self.seed_resize_from_w = p.seed_resize_from_w diff --git a/modules/processing_callbacks.py b/modules/processing_callbacks.py index 52142d44b..8446c5c68 100644 --- a/modules/processing_callbacks.py +++ b/modules/processing_callbacks.py @@ -84,7 +84,7 @@ def diffusers_callback(pipe, step: int, timestep: int, kwargs: dict): kwargs[key] = kwargs[key].chunk(2)[-1] try: if hasattr(pipe, "_unpack_latents") and hasattr(pipe, "vae_scale_factor"): # FLUX - if p.hr_upscaler is not None and p.hr_upscaler != 'None': + if p.hr_resize_mode > 0 and (p.hr_upscaler != 'None' or p.hr_resize_mode == 5): width = max(getattr(p, 'width', 0), getattr(p, 'hr_upscale_to_x', 0)) height = max(getattr(p, 'height', 0), getattr(p, 'hr_upscale_to_y', 0)) else: diff --git a/modules/processing_class.py b/modules/processing_class.py index 31f6fde40..fb3b5d73f 100644 --- a/modules/processing_class.py +++ b/modules/processing_class.py @@ -81,6 +81,8 @@ class StableDiffusionProcessing: self.enable_hr = None self.hr_scale = None self.hr_upscaler = None + self.hr_resize_mode = 0 + self.hr_resize_context = 'None' self.hr_resize_x = 0 self.hr_resize_y = 0 self.hr_upscale_to_x = 0 @@ -187,13 +189,15 @@ class StableDiffusionProcessing: class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): - def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_force: bool = False, hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): + def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_force: bool = False, hr_resize_mode: int = 0, hr_resize_context: str = 'None', hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs): super().__init__(**kwargs) self.enable_hr = enable_hr self.denoising_strength = denoising_strength self.hr_scale = hr_scale self.hr_upscaler = hr_upscaler + self.hr_resize_mode = hr_resize_mode + self.hr_resize_context = hr_resize_context self.hr_force = hr_force self.hr_second_pass_steps = hr_second_pass_steps self.hr_resize_x = hr_resize_x @@ -241,6 +245,9 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): elif self.hr_resize_x == 0: self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height self.hr_upscale_to_y = self.hr_resize_y + elif self.hr_resize_x > 0 and self.hr_resize_y > 0 and shared.native: + self.hr_upscale_to_x = self.hr_resize_x + self.hr_upscale_to_y = self.hr_resize_y else: target_w = self.hr_resize_x target_h = self.hr_resize_y diff --git a/modules/processing_diffusers.py b/modules/processing_diffusers.py index a675d799f..b544cd899 100644 --- a/modules/processing_diffusers.py +++ b/modules/processing_diffusers.py @@ -153,8 +153,8 @@ def process_diffusers(p: processing.StableDiffusionProcessing): shared.sd_model.restore_pipeline() # upscale - if hasattr(p, 'height') and hasattr(p, 'width') and p.hr_upscaler is not None and p.hr_upscaler != 'None': - shared.log.info(f'Upscale: upscaler="{p.hr_upscaler}" resize={p.hr_resize_x}x{p.hr_resize_y} upscale={p.hr_upscale_to_x}x{p.hr_upscale_to_y}') + if hasattr(p, 'height') and hasattr(p, 'width') and p.hr_resize_mode >0 and (p.hr_upscaler != 'None' or p.hr_resize_mode == 5): + shared.log.info(f'Upscale: mode={p.hr_resize_mode} upscaler="{p.hr_upscaler}" context="{p.hr_resize_context}" resize={p.hr_resize_x}x{p.hr_resize_y} upscale={p.hr_upscale_to_x}x{p.hr_upscale_to_y}') p.ops.append('upscale') if shared.opts.save and not p.do_not_save_samples and shared.opts.save_images_before_highres_fix and hasattr(shared.sd_model, 'vae'): save_intermediate(p, latents=output.images, suffix="-before-hires") @@ -304,7 +304,7 @@ def process_diffusers(p: processing.StableDiffusionProcessing): shared.log.debug(f'Generated: frames={len(output.frames[0])}') output.images = output.frames[0] if hasattr(shared.sd_model, "vae") and output.images is not None and len(output.images) > 0: - if p.hr_upscaler is not None and p.hr_upscaler != 'None': + if p.hr_resize_mode > 0 and (p.hr_upscaler != 'None' or p.hr_resize_mode == 5): width = max(getattr(p, 'width', 0), getattr(p, 'hr_upscale_to_x', 0)) height = max(getattr(p, 'height', 0), getattr(p, 'hr_upscale_to_y', 0)) else: diff --git a/modules/processing_helpers.py b/modules/processing_helpers.py index 31e8c3ba4..82f68ca35 100644 --- a/modules/processing_helpers.py +++ b/modules/processing_helpers.py @@ -396,7 +396,7 @@ def resize_hires(p, latents): # input=latents output=pil if not latent_upscaler resized_images = [] for img in first_pass_images: if latent_upscaler is None: - resized_image = images.resize_image(1, img, p.hr_upscale_to_x, p.hr_upscale_to_y, upscaler_name=p.hr_upscaler) + resized_image = images.resize_image(p.hr_resize_mode, img, p.hr_upscale_to_x, p.hr_upscale_to_y, upscaler_name=p.hr_upscaler, context=p.hr_resize_context) else: resized_image = img resized_images.append(resized_image) diff --git a/modules/processing_info.py b/modules/processing_info.py index 95e573f21..ac05aa58d 100644 --- a/modules/processing_info.py +++ b/modules/processing_info.py @@ -71,13 +71,16 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No args["Variation seed"] = all_subseeds[index] if p.subseed_strength > 0 else None args["Variation strength"] = p.subseed_strength if p.subseed_strength > 0 else None if 'hires' in p.ops or 'upscale' in p.ops: + is_resize = p.hr_resize_mode > 0 and (p.hr_upscaler != 'None' or p.hr_resize_mode == 5) args["Second pass"] = p.enable_hr args["Hires force"] = p.hr_force args["Hires steps"] = p.hr_second_pass_steps - args["Hires upscaler"] = p.hr_upscaler if p.hr_upscaler is not None and p.hr_upscaler != 'None' else None - args["Hires upscale"] = p.hr_scale if p.hr_upscaler is not None and p.hr_upscaler != 'None' else None - args["Hires resize"] = f"{p.hr_resize_x}x{p.hr_resize_y}" if p.hr_upscaler is not None and p.hr_upscaler != 'None' else None - args["Hires size"] = f"{p.hr_upscale_to_x}x{p.hr_upscale_to_y}" if p.hr_upscaler is not None and p.hr_upscaler != 'None' else None + args["HiRes resize mode"] = p.hr_resize_mode if is_resize else None + args["HiRes resize context"] = p.hr_resize_context if p.hr_resize_mode == 5 else None + args["Hires upscaler"] = p.hr_upscaler if is_resize else None + args["Hires scale"] = p.hr_scale if is_resize else None + args["Hires resize"] = f"{p.hr_resize_x}x{p.hr_resize_y}" if is_resize else None + args["Hires size"] = f"{p.hr_upscale_to_x}x{p.hr_upscale_to_y}" if is_resize else None args["Denoising strength"] = p.denoising_strength args["Hires sampler"] = p.hr_sampler_name args["Image CFG scale"] = p.image_cfg_scale diff --git a/modules/shared.py b/modules/shared.py index 4ab82569c..e675ed39b 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -843,6 +843,7 @@ options_templates.update(options_section(('extra_networks', "Networks"), { "extra_networks_sidebar_width": OptionInfo(35, "UI sidebar width (%)", gr.Slider, {"minimum": 10, "maximum": 80, "step": 1}), "extra_networks_card_size": OptionInfo(160, "UI card size (px)", gr.Slider, {"minimum": 20, "maximum": 2000, "step": 1}), "extra_networks_card_square": OptionInfo(True, "UI disable variable aspect ratio"), + "extra_networks_fetch": OptionInfo(True, "UI fetch network info on mouse-over"), "extra_networks_card_fit": OptionInfo("cover", "UI image contain method", gr.Radio, {"choices": ["contain", "cover", "fill"], "visible": False}), "extra_networks_sep2": OptionInfo("

Extra networks general

", "", gr.HTML), "extra_network_reference": OptionInfo(False, "Use reference values when available", gr.Checkbox), diff --git a/modules/txt2img.py b/modules/txt2img.py index 22ff74d3e..e438c2e47 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -18,13 +18,13 @@ def txt2img(id_task, 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, + hr_scale, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative, hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, override_settings_texts, *args): - debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative={negative_prompt}|styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|hr_sampler_index={hr_sampler_index}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|hidiffusion={hidiffusion}|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}') + debug(f'txt2img: id_task={id_task}|prompt={prompt}|negative={negative_prompt}|styles={prompt_styles}|steps={steps}|sampler_index={sampler_index}|hr_sampler_index={hr_sampler_index}|full_quality={full_quality}|restore_faces={restore_faces}|tiling={tiling}|hidiffusion={hidiffusion}|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_resize_mode={hr_resize_mode}|hr_resize_context={hr_resize_context}|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') @@ -71,6 +71,8 @@ def txt2img(id_task, enable_hr=enable_hr, denoising_strength=denoising_strength, hr_scale=hr_scale, + hr_resize_mode=hr_resize_mode, + hr_resize_context=hr_resize_context, hr_upscaler=hr_upscaler, hr_force=hr_force, hr_second_pass_steps=hr_second_pass_steps, diff --git a/modules/ui_common.py b/modules/ui_common.py index 9f36ba28e..e168e6981 100644 --- a/modules/ui_common.py +++ b/modules/ui_common.py @@ -42,7 +42,7 @@ def infotext_to_html(text): negative = res.get('Negative prompt', '') res.pop('Prompt', None) res.pop('Negative prompt', None) - params = [f'{k}: {v}' for k, v in res.items() if v is not None] + params = [f'{k}: {v}' for k, v in res.items() if v is not None and 'size-' not in k.lower()] params = '| '.join(params) if len(params) > 0 else '' code = '' if len(prompt) > 0: diff --git a/modules/ui_control.py b/modules/ui_control.py index cfe1f59ca..eab565b04 100644 --- a/modules/ui_control.py +++ b/modules/ui_control.py @@ -128,7 +128,7 @@ def create_ui(_blocks: gr.Blocks=None): video_interpolate = gr.Slider(label='Interpolate frames', minimum=0, maximum=24, step=1, value=0, visible=False, elem_id="control_video_interpolate") video_type.change(fn=helpers.video_type_change, inputs=[video_type], outputs=[video_duration, video_loop, video_pad, video_interpolate]) - enable_hr, hr_sampler_index, hr_denoising_strength, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('control') + enable_hr, hr_sampler_index, hr_denoising_strength, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('control') with gr.Row(): override_settings = ui_common.create_override_inputs('control') @@ -508,7 +508,7 @@ def create_ui(_blocks: gr.Blocks=None): resize_mode_after, resize_name_after, resize_context_after, width_after, height_after, scale_by_after, selected_scale_tab_after, resize_mode_mask, resize_name_mask, resize_context_mask, width_mask, height_mask, scale_by_mask, selected_scale_tab_mask, denoising_strength, batch_count, batch_size, - enable_hr, hr_sampler_index, hr_denoising_strength, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, + enable_hr, hr_sampler_index, hr_denoising_strength, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative, video_skip_frames, video_type, video_duration, video_loop, video_pad, video_interpolate, ] diff --git a/modules/ui_sections.py b/modules/ui_sections.py index f3fe6c137..245925785 100644 --- a/modules/ui_sections.py +++ b/modules/ui_sections.py @@ -280,12 +280,15 @@ def create_hires_inputs(tab): with gr.Group(): with gr.Row(elem_id=f"{tab}_hires_row1"): enable_hr = gr.Checkbox(label='Enable second pass', value=False, elem_id=f"{tab}_enable_hr") + """ with gr.Row(elem_id=f"{tab}_hires_fix_row1", variant="compact"): hr_upscaler = gr.Dropdown(label="Upscaler", elem_id=f"{tab}_hr_upscaler", choices=[*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]], value=shared.latent_upscale_default_mode) hr_scale = gr.Slider(minimum=0.1, maximum=8.0, step=0.05, label="Rescale by", value=2.0, elem_id=f"{tab}_hr_scale") with gr.Row(elem_id=f"{tab}_hires_fix_row3", variant="compact"): hr_resize_x = gr.Slider(minimum=0, maximum=4096, step=8, label="Width resize", value=0, elem_id=f"{tab}_hr_resize_x") hr_resize_y = gr.Slider(minimum=0, maximum=4096, step=8, label="Height resize", value=0, elem_id=f"{tab}_hr_resize_y") + """ + hr_resize_mode, hr_upscaler, hr_resize_context, hr_resize_x, hr_resize_y, hr_scale, _selected_scale_tab = create_resize_inputs(tab, None, accordion=False, latent=True, non_zero=False) with gr.Row(elem_id=f"{tab}_hires_fix_row2", variant="compact"): hr_force = gr.Checkbox(label='Force HiRes', value=False, elem_id=f"{tab}_hr_force") hr_sampler_index = gr.Dropdown(label='Secondary sampler', elem_id=f"{tab}_sampling_alt", choices=[x.name for x in sd_samplers.samplers], value='Same as primary', type="index") @@ -300,14 +303,14 @@ def create_hires_inputs(tab): refiner_prompt = gr.Textbox(value='', label='Secondary prompt', elem_id=f"{tab}_refiner_prompt") with gr.Row(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, hr_sampler_index, denoising_strength, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative + return enable_hr, hr_sampler_index, denoising_strength, hr_resize_mode, hr_resize_context, 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 create_resize_inputs(tab, images, accordion=True, latent=False): +def create_resize_inputs(tab, images, accordion=True, latent=False, non_zero=True): 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") if accordion else gr.Group(): with gr.Row(): - resize_mode = gr.Dropdown(label="Mode", elem_id=f"{tab}_resize_mode", choices=shared.resize_modes, type="index", value='Fixed') + resize_mode = gr.Dropdown(label="Mode" if non_zero else "Resize mode", elem_id=f"{tab}_resize_mode", choices=shared.resize_modes, type="index", value='Fixed') resize_name = gr.Dropdown(label="Method", elem_id=f"{tab}_resize_name", choices=([] if not latent else list(shared.latent_upscale_modes)) + [x.name for x in shared.sd_upscalers], value=shared.latent_upscale_default_mode, visible=True) resize_context_choices = ["Add with forward", "Remove with forward", "Add with backward", "Remove with backward"] resize_context = gr.Dropdown(label="Context", elem_id=f"{tab}_resize_context", choices=resize_context_choices, value=resize_context_choices[0], visible=False) @@ -316,19 +319,19 @@ def create_resize_inputs(tab, images, accordion=True, latent=False): def resize_mode_change(mode): if mode is None or mode == 0: return gr.update(visible=False), gr.update(visible=False) - return gr.update(visible=(mode != 5)), gr.update(visible=(mode == 5)) + return gr.update(visible=mode != 5), gr.update(visible=mode == 5) resize_mode.change(fn=resize_mode_change, inputs=[resize_mode], outputs=[resize_name, resize_context]) with gr.Row(visible=True) as _resize_group: with gr.Column(elem_id=f"{tab}_column_size"): selected_scale_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated - with gr.Tabs(elem_id=f"{tab}_scale_tabs"): - with gr.Tab(label="Fixed", elem_id=f"{tab}_scale_tab_fixed") as tab_scale_to: + with gr.Tabs(elem_id=f"{tab}_scale_tabs", selected=0 if non_zero else 1): + with gr.Tab(label="Fixed", id=0, elem_id=f"{tab}_scale_tab_fixed") as tab_scale_to: with gr.Row(): with gr.Column(elem_id=f"{tab}_column_size_fixed"): with gr.Row(): - width = gr.Slider(minimum=64, maximum=8192, step=8, label="Width", value=512, elem_id=f"{tab}_width") - height = gr.Slider(minimum=64, maximum=8192, step=8, label="Height", value=512, elem_id=f"{tab}_height") + width = gr.Slider(minimum=64 if non_zero else 0, maximum=8192, step=8, label="Width" if non_zero else "Resize width", value=1024 if non_zero else 0, elem_id=f"{tab}_width") + height = gr.Slider(minimum=64 if non_zero else 0, maximum=8192, step=8, label="Height" if non_zero else "Resize height", value=1024 if non_zero else 0, elem_id=f"{tab}_height") ar_list = ['AR'] + [x.strip() for x in shared.opts.aspect_ratios.split(',') if x.strip() != ''] ar_dropdown = gr.Dropdown(show_label=False, interactive=True, choices=ar_list, value=ar_list[0], elem_id=f"{tab}_ar", elem_classes=["ar-dropdown"]) for c in [ar_dropdown, width, height]: @@ -338,10 +341,11 @@ def create_resize_inputs(tab, images, accordion=True, latent=False): detect_image_size_btn = ToolButton(value=ui_symbols.detect, elem_id=f"{tab}_detect_image_size_btn") el = tab.split('_')[0] detect_image_size_btn.click(fn=lambda w, h, _: (w or gr.update(), h or gr.update()), _js=f'currentImageResolution{el}', inputs=[dummy_component, dummy_component, dummy_component], outputs=[width, height], show_progress=False) - with gr.Tab(label="Scale", elem_id=f"{tab}_scale_tab_scale") as tab_scale_by: - scale_by = gr.Slider(minimum=0.05, maximum=8.0, step=0.05, label="Scale", value=1.0, elem_id=f"{tab}_scale") - for component in images: - component.change(fn=lambda: None, _js="updateImg2imgResizeToTextAfterChangingImage", inputs=[], outputs=[], show_progress=False) + with gr.Tab(label="Scale", id=1, elem_id=f"{tab}_scale_tab_scale") as tab_scale_by: + scale_by = gr.Slider(minimum=0.05, maximum=8.0, step=0.05, label="Scale" if non_zero else "Resize scale", value=1.0, elem_id=f"{tab}_scale") + if images is not None: + 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]) diff --git a/modules/ui_txt2img.py b/modules/ui_txt2img.py index fca679a70..03e773e04 100644 --- a/modules/ui_txt2img.py +++ b/modules/ui_txt2img.py @@ -48,7 +48,7 @@ def create_ui(): seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w = ui_sections.create_seed_inputs('txt2img') _cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, pag_scale, pag_adaptive, _cfg_end = ui_sections.create_advanced_inputs('txt2img', base=False) hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio = ui_sections.create_correction_inputs('txt2img') - enable_hr, hr_sampler_index, denoising_strength, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('txt2img') + enable_hr, hr_sampler_index, denoising_strength, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_scale, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative = ui_sections.create_hires_inputs('txt2img') override_settings = ui_common.create_override_inputs('txt2img') with gr.Group(elem_id="txt2img_script_container"): @@ -70,7 +70,7 @@ def create_ui(): 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, + hr_scale, hr_resize_mode, hr_resize_context, hr_upscaler, hr_force, hr_second_pass_steps, hr_resize_x, hr_resize_y, refiner_steps, refiner_start, refiner_prompt, refiner_negative, hdr_mode, hdr_brightness, hdr_color, hdr_sharpen, hdr_clamp, hdr_boundary, hdr_threshold, hdr_maximize, hdr_max_center, hdr_max_boundry, hdr_color_picker, hdr_tint_ratio, override_settings, @@ -118,14 +118,19 @@ def create_ui(): (hidiffusion, "HiDiffusion"), # second pass (enable_hr, "Second pass"), - (hr_sampler_index, "Hires sampler"), (denoising_strength, "Denoising strength"), + (hr_sampler_index, "Hires sampler"), + (hr_resize_mode, "Hires resize mode"), + (hr_resize_context, "Hires resize context"), (hr_upscaler, "Hires upscaler"), (hr_force, "Hires force"), (hr_second_pass_steps, "Hires steps"), (hr_scale, "Hires upscale"), + (hr_scale, "Hires scale"), (hr_resize_x, "Hires resize-1"), (hr_resize_y, "Hires resize-2"), + (hr_resize_x, "Hires size-1"), + (hr_resize_y, "Hires size-2"), # refiner (refiner_start, "Refiner start"), (refiner_steps, "Refiner steps"), diff --git a/scripts/postprocessing_upscale.py b/scripts/postprocessing_upscale.py index 066aa30d6..e19d577ee 100644 --- a/scripts/postprocessing_upscale.py +++ b/scripts/postprocessing_upscale.py @@ -21,8 +21,8 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing): with gr.TabItem('Scale to', elem_id="extras_scale_to_tab") as tab_scale_to: with gr.Row(): with gr.Row(elem_id="upscaling_column_size"): - upscaling_resize_w = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=512, elem_id="extras_upscaling_resize_w") - upscaling_resize_h = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=512, elem_id="extras_upscaling_resize_h") + upscaling_resize_w = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=1024, elem_id="extras_upscaling_resize_w") + upscaling_resize_h = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=1024, elem_id="extras_upscaling_resize_h") upscaling_res_switch_btn = ToolButton(value=symbols.switch, elem_id="upscaling_res_switch_btn") upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop") diff --git a/scripts/x_adapter.py b/scripts/x_adapter.py index 58d6fb9eb..7c1341701 100644 --- a/scripts/x_adapter.py +++ b/scripts/x_adapter.py @@ -25,8 +25,8 @@ class Script(scripts.Script): model = gr.Dropdown(label='Adapter model', choices=['None'] + sd_models.checkpoint_tiles(), value='None') sampler = gr.Dropdown(label='Adapter sampler', choices=[s.name for s in sd_samplers.samplers], value='Default') with gr.Row(): - width = gr.Slider(label='Adapter width', minimum=64, maximum=2048, step=8, value=512) - height = gr.Slider(label='Adapter height', minimum=64, maximum=2048, step=8, value=512) + width = gr.Slider(label='Adapter width', minimum=64, maximum=2048, step=8, value=1024) + height = gr.Slider(label='Adapter height', minimum=64, maximum=2048, step=8, value=1024) with gr.Row(): start = gr.Slider(label='Adapter start', minimum=0.0, maximum=1.0, step=0.01, value=0.5) scale = gr.Slider(label='Adapter scale', minimum=0.0, maximum=1.0, step=0.01, value=1.0)