mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2025-05-03 10:29:00 +08:00
move seed, variation seed and variation seed strength to a single row, dump resize seed from UI
add a way for scripts to register a callback for before/after just a single component's creation
This commit is contained in:
parent
6aa26a26d5
commit
f0b72b8121
@ -116,7 +116,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=Fal
|
|||||||
process_images(p)
|
process_images(p)
|
||||||
|
|
||||||
|
|
||||||
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_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, 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_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args):
|
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_name: str, mask_blur: int, mask_alpha: float, inpainting_fill: int, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, 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_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, img2img_batch_use_png_info: bool, img2img_batch_png_info_props: list, img2img_batch_png_info_dir: str, request: gr.Request, *args):
|
||||||
override_settings = create_override_settings_dict(override_settings_texts)
|
override_settings = create_override_settings_dict(override_settings_texts)
|
||||||
|
|
||||||
is_batch = mode == 5
|
is_batch = mode == 5
|
||||||
@ -166,12 +166,6 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
|
|||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
negative_prompt=negative_prompt,
|
negative_prompt=negative_prompt,
|
||||||
styles=prompt_styles,
|
styles=prompt_styles,
|
||||||
seed=seed,
|
|
||||||
subseed=subseed,
|
|
||||||
subseed_strength=subseed_strength,
|
|
||||||
seed_resize_from_h=seed_resize_from_h,
|
|
||||||
seed_resize_from_w=seed_resize_from_w,
|
|
||||||
seed_enable_extras=seed_enable_extras,
|
|
||||||
sampler_name=sampler_name,
|
sampler_name=sampler_name,
|
||||||
batch_size=batch_size,
|
batch_size=batch_size,
|
||||||
n_iter=n_iter,
|
n_iter=n_iter,
|
||||||
|
95
modules/processing_scripts/seed.py
Normal file
95
modules/processing_scripts/seed.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import gradio as gr
|
||||||
|
|
||||||
|
from modules import scripts, ui, errors
|
||||||
|
from modules.shared import cmd_opts
|
||||||
|
from modules.ui_components import ToolButton
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptSeed(scripts.ScriptBuiltin):
|
||||||
|
section = "seed"
|
||||||
|
create_group = False
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.seed = None
|
||||||
|
self.reuse_seed = None
|
||||||
|
self.reuse_subseed = None
|
||||||
|
|
||||||
|
def title(self):
|
||||||
|
return "Seed"
|
||||||
|
|
||||||
|
def show(self, is_img2img):
|
||||||
|
return scripts.AlwaysVisible
|
||||||
|
|
||||||
|
def ui(self, is_img2img):
|
||||||
|
with gr.Row(elem_id=self.elem_id("seed_row")):
|
||||||
|
if cmd_opts.use_textbox_seed:
|
||||||
|
self.seed = gr.Textbox(label='Seed', value="", elem_id=self.elem_id("seed"))
|
||||||
|
else:
|
||||||
|
self.seed = gr.Number(label='Seed', value=-1, elem_id=self.elem_id("seed"), precision=0)
|
||||||
|
|
||||||
|
random_seed = ToolButton(ui.random_symbol, elem_id=self.elem_id("random_seed"), label='Random seed')
|
||||||
|
reuse_seed = ToolButton(ui.reuse_symbol, elem_id=self.elem_id("reuse_seed"), label='Reuse seed')
|
||||||
|
|
||||||
|
subseed = gr.Number(label='Variation seed', value=-1, elem_id=self.elem_id("subseed"), precision=0)
|
||||||
|
|
||||||
|
random_subseed = ToolButton(ui.random_symbol, elem_id=self.elem_id("random_subseed"))
|
||||||
|
reuse_subseed = ToolButton(ui.reuse_symbol, elem_id=self.elem_id("reuse_subseed"))
|
||||||
|
|
||||||
|
subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=self.elem_id("subseed_strength"))
|
||||||
|
|
||||||
|
random_seed.click(fn=None, _js="function(){setRandomSeed('" + self.elem_id("seed") + "')}", show_progress=False, inputs=[], outputs=[])
|
||||||
|
random_subseed.click(fn=None, _js="function(){setRandomSeed('" + self.elem_id("subseed") + "')}", show_progress=False, inputs=[], outputs=[])
|
||||||
|
|
||||||
|
self.infotext_fields = [
|
||||||
|
(self.seed, "Seed"),
|
||||||
|
(subseed, "Variation seed"),
|
||||||
|
(subseed_strength, "Variation seed strength"),
|
||||||
|
]
|
||||||
|
|
||||||
|
self.on_after_component(lambda x: connect_reuse_seed(self.seed, reuse_seed, x.component, False), elem_id=f'generation_info_{self.tabname}')
|
||||||
|
self.on_after_component(lambda x: connect_reuse_seed(self.seed, reuse_subseed, x.component, True), elem_id=f'generation_info_{self.tabname}')
|
||||||
|
|
||||||
|
return self.seed, subseed, subseed_strength
|
||||||
|
|
||||||
|
def before_process(self, p, seed, subseed, subseed_strength):
|
||||||
|
p.seed = seed
|
||||||
|
|
||||||
|
if subseed_strength > 0:
|
||||||
|
p.subseed = subseed
|
||||||
|
p.subseed_strength = subseed_strength
|
||||||
|
|
||||||
|
|
||||||
|
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."""
|
||||||
|
|
||||||
|
def copy_seed(gen_info_string: str, index):
|
||||||
|
res = -1
|
||||||
|
|
||||||
|
try:
|
||||||
|
gen_info = json.loads(gen_info_string)
|
||||||
|
index -= gen_info.get('index_of_first_image', 0)
|
||||||
|
|
||||||
|
if is_subseed and gen_info.get('subseed_strength', 0) > 0:
|
||||||
|
all_subseeds = gen_info.get('all_subseeds', [-1])
|
||||||
|
res = all_subseeds[index if 0 <= index < len(all_subseeds) else 0]
|
||||||
|
else:
|
||||||
|
all_seeds = gen_info.get('all_seeds', [-1])
|
||||||
|
res = all_seeds[index if 0 <= index < len(all_seeds) else 0]
|
||||||
|
|
||||||
|
except json.decoder.JSONDecodeError:
|
||||||
|
if gen_info_string:
|
||||||
|
errors.report(f"Error parsing JSON generation info: {gen_info_string}")
|
||||||
|
|
||||||
|
return [res, gr.update()]
|
||||||
|
|
||||||
|
reuse_seed.click(
|
||||||
|
fn=copy_seed,
|
||||||
|
_js="(x, y) => [x, selected_gallery_index()]",
|
||||||
|
show_progress=False,
|
||||||
|
inputs=[generation_info, seed],
|
||||||
|
outputs=[seed, seed]
|
||||||
|
)
|
@ -3,6 +3,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
import inspect
|
import inspect
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
import gradio as gr
|
import gradio as gr
|
||||||
|
|
||||||
@ -21,6 +22,11 @@ class PostprocessBatchListArgs:
|
|||||||
self.images = images
|
self.images = images
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OnComponent:
|
||||||
|
component: gr.blocks.Block
|
||||||
|
|
||||||
|
|
||||||
class Script:
|
class Script:
|
||||||
name = None
|
name = None
|
||||||
"""script's internal name derived from title"""
|
"""script's internal name derived from title"""
|
||||||
@ -35,6 +41,7 @@ class Script:
|
|||||||
|
|
||||||
is_txt2img = False
|
is_txt2img = False
|
||||||
is_img2img = False
|
is_img2img = False
|
||||||
|
tabname = None
|
||||||
|
|
||||||
group = None
|
group = None
|
||||||
"""A gr.Group component that has all script's UI inside it."""
|
"""A gr.Group component that has all script's UI inside it."""
|
||||||
@ -55,6 +62,12 @@ class Script:
|
|||||||
api_info = None
|
api_info = None
|
||||||
"""Generated value of type modules.api.models.ScriptInfo with information about the script for API"""
|
"""Generated value of type modules.api.models.ScriptInfo with information about the script for API"""
|
||||||
|
|
||||||
|
on_before_component_elem_id = []
|
||||||
|
"""list of callbacks to be called before a component with an elem_id is created"""
|
||||||
|
|
||||||
|
on_after_component_elem_id = []
|
||||||
|
"""list of callbacks to be called after a component with an elem_id is created"""
|
||||||
|
|
||||||
def title(self):
|
def title(self):
|
||||||
"""this function should return the title of the script. This is what will be displayed in the dropdown menu."""
|
"""this function should return the title of the script. This is what will be displayed in the dropdown menu."""
|
||||||
|
|
||||||
@ -215,6 +228,24 @@ class Script:
|
|||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def on_before_component(self, callback, *, elem_id):
|
||||||
|
"""
|
||||||
|
Calls callback before a component is created. The callback function is called with a single argument of type OnComponent.
|
||||||
|
|
||||||
|
This function is an alternative to before_component in that it also cllows to run before a component is created, but
|
||||||
|
it doesn't require to be called for every created component - just for the one you need.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.on_before_component_elem_id.append((elem_id, callback))
|
||||||
|
|
||||||
|
def on_after_component(self, callback, *, elem_id):
|
||||||
|
"""
|
||||||
|
Calls callback after a component is created. The callback function is called with a single argument of type OnComponent.
|
||||||
|
"""
|
||||||
|
|
||||||
|
self.on_after_component_elem_id.append((elem_id, callback))
|
||||||
|
|
||||||
|
|
||||||
def describe(self):
|
def describe(self):
|
||||||
"""unused"""
|
"""unused"""
|
||||||
return ""
|
return ""
|
||||||
@ -236,6 +267,17 @@ class Script:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ScriptBuiltin(Script):
|
||||||
|
|
||||||
|
def elem_id(self, item_id):
|
||||||
|
"""helper function to generate id for a HTML element, constructs final id out of tab and user-supplied item_id"""
|
||||||
|
|
||||||
|
need_tabname = self.show(True) == self.show(False)
|
||||||
|
tabname = ('img2img' if self.is_img2img else 'txt2txt') + "_" if need_tabname else ""
|
||||||
|
|
||||||
|
return f'{tabname}{item_id}'
|
||||||
|
|
||||||
|
|
||||||
current_basedir = paths.script_path
|
current_basedir = paths.script_path
|
||||||
|
|
||||||
|
|
||||||
@ -354,10 +396,17 @@ class ScriptRunner:
|
|||||||
self.selectable_scripts = []
|
self.selectable_scripts = []
|
||||||
self.alwayson_scripts = []
|
self.alwayson_scripts = []
|
||||||
self.titles = []
|
self.titles = []
|
||||||
|
self.title_map = {}
|
||||||
self.infotext_fields = []
|
self.infotext_fields = []
|
||||||
self.paste_field_names = []
|
self.paste_field_names = []
|
||||||
self.inputs = [None]
|
self.inputs = [None]
|
||||||
|
|
||||||
|
self.on_before_component_elem_id = {}
|
||||||
|
"""dict of callbacks to be called before an element is created; key=elem_id, value=list of callbacks"""
|
||||||
|
|
||||||
|
self.on_after_component_elem_id = {}
|
||||||
|
"""dict of callbacks to be called after an element is created; key=elem_id, value=list of callbacks"""
|
||||||
|
|
||||||
def initialize_scripts(self, is_img2img):
|
def initialize_scripts(self, is_img2img):
|
||||||
from modules import scripts_auto_postprocessing
|
from modules import scripts_auto_postprocessing
|
||||||
|
|
||||||
@ -372,6 +421,7 @@ class ScriptRunner:
|
|||||||
script.filename = script_data.path
|
script.filename = script_data.path
|
||||||
script.is_txt2img = not is_img2img
|
script.is_txt2img = not is_img2img
|
||||||
script.is_img2img = is_img2img
|
script.is_img2img = is_img2img
|
||||||
|
script.tabname = "img2img" if is_img2img else "txt2img"
|
||||||
|
|
||||||
visibility = script.show(script.is_img2img)
|
visibility = script.show(script.is_img2img)
|
||||||
|
|
||||||
@ -446,6 +496,8 @@ class ScriptRunner:
|
|||||||
self.inputs = [None]
|
self.inputs = [None]
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
|
all_titles = [wrap_call(script.title, script.filename, "title") or script.filename for script in self.scripts]
|
||||||
|
self.title_map = {title.lower(): script for title, script in zip(all_titles, self.scripts)}
|
||||||
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
|
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
|
||||||
|
|
||||||
self.setup_ui_for_section(None)
|
self.setup_ui_for_section(None)
|
||||||
@ -492,6 +544,13 @@ class ScriptRunner:
|
|||||||
self.infotext_fields.append((dropdown, lambda x: gr.update(value=x.get('Script', 'None'))))
|
self.infotext_fields.append((dropdown, lambda x: gr.update(value=x.get('Script', 'None'))))
|
||||||
self.infotext_fields.extend([(script.group, onload_script_visibility) for script in self.selectable_scripts])
|
self.infotext_fields.extend([(script.group, onload_script_visibility) for script in self.selectable_scripts])
|
||||||
|
|
||||||
|
for script in self.scripts:
|
||||||
|
for elem_id, callback in script.on_before_component_elem_id:
|
||||||
|
self.on_before_component_elem_id.get(elem_id, []).append((callback, script))
|
||||||
|
|
||||||
|
for elem_id, callback in script.on_after_component_elem_id:
|
||||||
|
self.on_after_component_elem_id.get(elem_id, []).append((callback, script))
|
||||||
|
|
||||||
return self.inputs
|
return self.inputs
|
||||||
|
|
||||||
def run(self, p, *args):
|
def run(self, p, *args):
|
||||||
@ -585,6 +644,13 @@ class ScriptRunner:
|
|||||||
errors.report(f"Error running postprocess_image: {script.filename}", exc_info=True)
|
errors.report(f"Error running postprocess_image: {script.filename}", exc_info=True)
|
||||||
|
|
||||||
def before_component(self, component, **kwargs):
|
def before_component(self, component, **kwargs):
|
||||||
|
for callbacks in self.on_before_component_elem_id.get(kwargs.get("elem_id"), []):
|
||||||
|
for callback, script in callbacks:
|
||||||
|
try:
|
||||||
|
callback(OnComponent(component=component))
|
||||||
|
except Exception:
|
||||||
|
errors.report(f"Error running on_before_component: {script.filename}", exc_info=True)
|
||||||
|
|
||||||
for script in self.scripts:
|
for script in self.scripts:
|
||||||
try:
|
try:
|
||||||
script.before_component(component, **kwargs)
|
script.before_component(component, **kwargs)
|
||||||
@ -592,12 +658,22 @@ class ScriptRunner:
|
|||||||
errors.report(f"Error running before_component: {script.filename}", exc_info=True)
|
errors.report(f"Error running before_component: {script.filename}", exc_info=True)
|
||||||
|
|
||||||
def after_component(self, component, **kwargs):
|
def after_component(self, component, **kwargs):
|
||||||
|
for callbacks in self.on_after_component_elem_id.get(component.elem_id, []):
|
||||||
|
for callback, script in callbacks:
|
||||||
|
try:
|
||||||
|
callback(OnComponent(component=component))
|
||||||
|
except Exception:
|
||||||
|
errors.report(f"Error running on_after_component: {script.filename}", exc_info=True)
|
||||||
|
|
||||||
for script in self.scripts:
|
for script in self.scripts:
|
||||||
try:
|
try:
|
||||||
script.after_component(component, **kwargs)
|
script.after_component(component, **kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
errors.report(f"Error running after_component: {script.filename}", exc_info=True)
|
errors.report(f"Error running after_component: {script.filename}", exc_info=True)
|
||||||
|
|
||||||
|
def script(self, title):
|
||||||
|
return self.title_map.get(title.lower())
|
||||||
|
|
||||||
def reload_sources(self, cache):
|
def reload_sources(self, cache):
|
||||||
for si, script in list(enumerate(self.scripts)):
|
for si, script in list(enumerate(self.scripts)):
|
||||||
args_from = script.args_from
|
args_from = script.args_from
|
||||||
@ -616,7 +692,6 @@ class ScriptRunner:
|
|||||||
self.scripts[si].args_from = args_from
|
self.scripts[si].args_from = args_from
|
||||||
self.scripts[si].args_to = args_to
|
self.scripts[si].args_to = args_to
|
||||||
|
|
||||||
|
|
||||||
def before_hr(self, p):
|
def before_hr(self, p):
|
||||||
for script in self.alwayson_scripts:
|
for script in self.alwayson_scripts:
|
||||||
try:
|
try:
|
||||||
|
@ -73,6 +73,7 @@ ui_reorder_categories_builtin_items = [
|
|||||||
"checkboxes",
|
"checkboxes",
|
||||||
"dimensions",
|
"dimensions",
|
||||||
"cfg",
|
"cfg",
|
||||||
|
"denoising",
|
||||||
"seed",
|
"seed",
|
||||||
"batch",
|
"batch",
|
||||||
"override_settings",
|
"override_settings",
|
||||||
|
@ -9,7 +9,7 @@ from modules.ui import plaintext_to_html
|
|||||||
import gradio as gr
|
import gradio as gr
|
||||||
|
|
||||||
|
|
||||||
def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args):
|
def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_name: str, n_iter: int, batch_size: int, cfg_scale: float, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, hr_checkpoint_name: str, hr_sampler_name: str, hr_prompt: str, hr_negative_prompt, override_settings_texts, request: gr.Request, *args):
|
||||||
override_settings = create_override_settings_dict(override_settings_texts)
|
override_settings = create_override_settings_dict(override_settings_texts)
|
||||||
|
|
||||||
p = processing.StableDiffusionProcessingTxt2Img(
|
p = processing.StableDiffusionProcessingTxt2Img(
|
||||||
@ -19,12 +19,6 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step
|
|||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
styles=prompt_styles,
|
styles=prompt_styles,
|
||||||
negative_prompt=negative_prompt,
|
negative_prompt=negative_prompt,
|
||||||
seed=seed,
|
|
||||||
subseed=subseed,
|
|
||||||
subseed_strength=subseed_strength,
|
|
||||||
seed_resize_from_h=seed_resize_from_h,
|
|
||||||
seed_resize_from_w=seed_resize_from_w,
|
|
||||||
seed_enable_extras=seed_enable_extras,
|
|
||||||
sampler_name=sampler_name,
|
sampler_name=sampler_name,
|
||||||
batch_size=batch_size,
|
batch_size=batch_size,
|
||||||
n_iter=n_iter,
|
n_iter=n_iter,
|
||||||
|
119
modules/ui.py
119
modules/ui.py
@ -1,5 +1,4 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import json
|
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@ -13,7 +12,7 @@ from PIL import Image, PngImagePlugin # noqa: F401
|
|||||||
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
|
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
|
||||||
|
|
||||||
from modules import gradio_extensons # noqa: F401
|
from modules import gradio_extensons # noqa: F401
|
||||||
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers, processing, ui_extra_networks
|
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers, processing, ui_extra_networks
|
||||||
from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML, InputAccordion
|
from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML, InputAccordion
|
||||||
from modules.paths import script_path
|
from modules.paths import script_path
|
||||||
from modules.ui_common import create_refresh_button
|
from modules.ui_common import create_refresh_button
|
||||||
@ -142,45 +141,6 @@ def interrogate_deepbooru(image):
|
|||||||
return gr.update() if prompt is None else prompt
|
return gr.update() if prompt is None else prompt
|
||||||
|
|
||||||
|
|
||||||
def create_seed_inputs(target_interface):
|
|
||||||
with FormRow(elem_id=f"{target_interface}_seed_row", variant="compact"):
|
|
||||||
if cmd_opts.use_textbox_seed:
|
|
||||||
seed = gr.Textbox(label='Seed', value="", elem_id=f"{target_interface}_seed")
|
|
||||||
else:
|
|
||||||
seed = gr.Number(label='Seed', value=-1, elem_id=f"{target_interface}_seed", precision=0)
|
|
||||||
|
|
||||||
random_seed = ToolButton(random_symbol, elem_id=f"{target_interface}_random_seed", label='Random seed')
|
|
||||||
reuse_seed = ToolButton(reuse_symbol, elem_id=f"{target_interface}_reuse_seed", label='Reuse seed')
|
|
||||||
|
|
||||||
seed_checkbox = gr.Checkbox(label='Extra', elem_id=f"{target_interface}_subseed_show", value=False)
|
|
||||||
|
|
||||||
# Components to show/hide based on the 'Extra' checkbox
|
|
||||||
seed_extras = []
|
|
||||||
|
|
||||||
with FormRow(visible=False, elem_id=f"{target_interface}_subseed_row") as seed_extra_row_1:
|
|
||||||
seed_extras.append(seed_extra_row_1)
|
|
||||||
subseed = gr.Number(label='Variation seed', value=-1, elem_id=f"{target_interface}_subseed", precision=0)
|
|
||||||
random_subseed = ToolButton(random_symbol, elem_id=f"{target_interface}_random_subseed")
|
|
||||||
reuse_subseed = ToolButton(reuse_symbol, elem_id=f"{target_interface}_reuse_subseed")
|
|
||||||
subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=f"{target_interface}_subseed_strength")
|
|
||||||
|
|
||||||
with FormRow(visible=False) as seed_extra_row_2:
|
|
||||||
seed_extras.append(seed_extra_row_2)
|
|
||||||
seed_resize_from_w = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from width", value=0, elem_id=f"{target_interface}_seed_resize_from_w")
|
|
||||||
seed_resize_from_h = gr.Slider(minimum=0, maximum=2048, step=8, label="Resize seed from height", value=0, elem_id=f"{target_interface}_seed_resize_from_h")
|
|
||||||
|
|
||||||
random_seed.click(fn=None, _js="function(){setRandomSeed('" + target_interface + "_seed')}", show_progress=False, inputs=[], outputs=[])
|
|
||||||
random_subseed.click(fn=None, _js="function(){setRandomSeed('" + target_interface + "_subseed')}", show_progress=False, inputs=[], outputs=[])
|
|
||||||
|
|
||||||
def change_visibility(show):
|
|
||||||
return {comp: gr_show(show) for comp in seed_extras}
|
|
||||||
|
|
||||||
seed_checkbox.change(change_visibility, show_progress=False, inputs=[seed_checkbox], outputs=seed_extras)
|
|
||||||
|
|
||||||
return seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def connect_clear_prompt(button):
|
def connect_clear_prompt(button):
|
||||||
"""Given clear button, prompt, and token_counter objects, setup clear prompt button click event"""
|
"""Given clear button, prompt, and token_counter objects, setup clear prompt button click event"""
|
||||||
button.click(
|
button.click(
|
||||||
@ -191,39 +151,6 @@ def connect_clear_prompt(button):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info: gr.Textbox, dummy_component, 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."""
|
|
||||||
def copy_seed(gen_info_string: str, index):
|
|
||||||
res = -1
|
|
||||||
|
|
||||||
try:
|
|
||||||
gen_info = json.loads(gen_info_string)
|
|
||||||
index -= gen_info.get('index_of_first_image', 0)
|
|
||||||
|
|
||||||
if is_subseed and gen_info.get('subseed_strength', 0) > 0:
|
|
||||||
all_subseeds = gen_info.get('all_subseeds', [-1])
|
|
||||||
res = all_subseeds[index if 0 <= index < len(all_subseeds) else 0]
|
|
||||||
else:
|
|
||||||
all_seeds = gen_info.get('all_seeds', [-1])
|
|
||||||
res = all_seeds[index if 0 <= index < len(all_seeds) else 0]
|
|
||||||
|
|
||||||
except json.decoder.JSONDecodeError:
|
|
||||||
if gen_info_string:
|
|
||||||
errors.report(f"Error parsing JSON generation info: {gen_info_string}")
|
|
||||||
|
|
||||||
return [res, gr_show(False)]
|
|
||||||
|
|
||||||
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]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def update_token_counter(text, steps):
|
def update_token_counter(text, steps):
|
||||||
try:
|
try:
|
||||||
text, _ = extra_networks.parse_prompt(text)
|
text, _ = extra_networks.parse_prompt(text)
|
||||||
@ -429,10 +356,8 @@ def create_ui():
|
|||||||
batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size")
|
batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="txt2img_batch_size")
|
||||||
|
|
||||||
elif category == "cfg":
|
elif category == "cfg":
|
||||||
cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="txt2img_cfg_scale")
|
with gr.Row():
|
||||||
|
cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="txt2img_cfg_scale")
|
||||||
elif category == "seed":
|
|
||||||
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('txt2img')
|
|
||||||
|
|
||||||
elif category == "checkboxes":
|
elif category == "checkboxes":
|
||||||
with FormRow(elem_classes="checkboxes-row", variant="compact"):
|
with FormRow(elem_classes="checkboxes-row", variant="compact"):
|
||||||
@ -509,9 +434,6 @@ def create_ui():
|
|||||||
|
|
||||||
txt2img_gallery, generation_info, html_info, html_log = create_output_panel("txt2img", opts.outdir_txt2img_samples)
|
txt2img_gallery, generation_info, html_info, html_log = create_output_panel("txt2img", opts.outdir_txt2img_samples)
|
||||||
|
|
||||||
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_args = dict(
|
txt2img_args = dict(
|
||||||
fn=wrap_gradio_gpu_call(modules.txt2img.txt2img, extra_outputs=[None, '', '']),
|
fn=wrap_gradio_gpu_call(modules.txt2img.txt2img, extra_outputs=[None, '', '']),
|
||||||
_js="submit",
|
_js="submit",
|
||||||
@ -525,8 +447,6 @@ def create_ui():
|
|||||||
batch_count,
|
batch_count,
|
||||||
batch_size,
|
batch_size,
|
||||||
cfg_scale,
|
cfg_scale,
|
||||||
seed,
|
|
||||||
subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox,
|
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
enable_hr,
|
enable_hr,
|
||||||
@ -577,15 +497,9 @@ def create_ui():
|
|||||||
(steps, "Steps"),
|
(steps, "Steps"),
|
||||||
(sampler_name, "Sampler"),
|
(sampler_name, "Sampler"),
|
||||||
(cfg_scale, "CFG scale"),
|
(cfg_scale, "CFG scale"),
|
||||||
(seed, "Seed"),
|
|
||||||
(width, "Size-1"),
|
(width, "Size-1"),
|
||||||
(height, "Size-2"),
|
(height, "Size-2"),
|
||||||
(batch_size, "Batch size"),
|
(batch_size, "Batch size"),
|
||||||
(seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d),
|
|
||||||
(subseed, "Variation seed"),
|
|
||||||
(subseed_strength, "Variation seed strength"),
|
|
||||||
(seed_resize_from_w, "Seed resize from-1"),
|
|
||||||
(seed_resize_from_h, "Seed resize from-2"),
|
|
||||||
(toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
(toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
||||||
(denoising_strength, "Denoising strength"),
|
(denoising_strength, "Denoising strength"),
|
||||||
(enable_hr, lambda d: "Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d)),
|
(enable_hr, lambda d: "Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d)),
|
||||||
@ -613,7 +527,7 @@ def create_ui():
|
|||||||
steps,
|
steps,
|
||||||
sampler_name,
|
sampler_name,
|
||||||
cfg_scale,
|
cfg_scale,
|
||||||
seed,
|
scripts.scripts_txt2img.script('Seed').seed,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
]
|
]
|
||||||
@ -783,15 +697,13 @@ def create_ui():
|
|||||||
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
|
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")
|
batch_size = gr.Slider(minimum=1, maximum=8, step=1, label='Batch size', value=1, elem_id="img2img_batch_size")
|
||||||
|
|
||||||
elif category == "cfg":
|
elif category == "denoising":
|
||||||
with FormGroup():
|
denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
|
||||||
with FormRow():
|
|
||||||
cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="img2img_cfg_scale")
|
|
||||||
image_cfg_scale = gr.Slider(minimum=0, maximum=3.0, step=0.05, label='Image CFG Scale', value=1.5, elem_id="img2img_image_cfg_scale", visible=False)
|
|
||||||
denoising_strength = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Denoising strength', value=0.75, elem_id="img2img_denoising_strength")
|
|
||||||
|
|
||||||
elif category == "seed":
|
elif category == "cfg":
|
||||||
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('img2img')
|
with gr.Row():
|
||||||
|
cfg_scale = gr.Slider(minimum=1.0, maximum=30.0, step=0.5, label='CFG Scale', value=7.0, elem_id="img2img_cfg_scale")
|
||||||
|
image_cfg_scale = gr.Slider(minimum=0, maximum=3.0, step=0.05, label='Image CFG Scale', value=1.5, elem_id="img2img_image_cfg_scale", visible=False)
|
||||||
|
|
||||||
elif category == "checkboxes":
|
elif category == "checkboxes":
|
||||||
with FormRow(elem_classes="checkboxes-row", variant="compact"):
|
with FormRow(elem_classes="checkboxes-row", variant="compact"):
|
||||||
@ -849,9 +761,6 @@ def create_ui():
|
|||||||
|
|
||||||
img2img_gallery, generation_info, html_info, html_log = create_output_panel("img2img", opts.outdir_img2img_samples)
|
img2img_gallery, generation_info, html_info, html_log = create_output_panel("img2img", opts.outdir_img2img_samples)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
img2img_args = dict(
|
img2img_args = dict(
|
||||||
fn=wrap_gradio_gpu_call(modules.img2img.img2img, extra_outputs=[None, '', '']),
|
fn=wrap_gradio_gpu_call(modules.img2img.img2img, extra_outputs=[None, '', '']),
|
||||||
_js="submit_img2img",
|
_js="submit_img2img",
|
||||||
@ -878,8 +787,6 @@ def create_ui():
|
|||||||
cfg_scale,
|
cfg_scale,
|
||||||
image_cfg_scale,
|
image_cfg_scale,
|
||||||
denoising_strength,
|
denoising_strength,
|
||||||
seed,
|
|
||||||
subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox,
|
|
||||||
selected_scale_tab,
|
selected_scale_tab,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
@ -966,15 +873,9 @@ def create_ui():
|
|||||||
(sampler_name, "Sampler"),
|
(sampler_name, "Sampler"),
|
||||||
(cfg_scale, "CFG scale"),
|
(cfg_scale, "CFG scale"),
|
||||||
(image_cfg_scale, "Image CFG scale"),
|
(image_cfg_scale, "Image CFG scale"),
|
||||||
(seed, "Seed"),
|
|
||||||
(width, "Size-1"),
|
(width, "Size-1"),
|
||||||
(height, "Size-2"),
|
(height, "Size-2"),
|
||||||
(batch_size, "Batch size"),
|
(batch_size, "Batch size"),
|
||||||
(seed_checkbox, lambda d: "Variation seed" in d or "Seed resize from-1" in d),
|
|
||||||
(subseed, "Variation seed"),
|
|
||||||
(subseed_strength, "Variation seed strength"),
|
|
||||||
(seed_resize_from_w, "Seed resize from-1"),
|
|
||||||
(seed_resize_from_h, "Seed resize from-2"),
|
|
||||||
(toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
(toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
|
||||||
(denoising_strength, "Denoising strength"),
|
(denoising_strength, "Denoising strength"),
|
||||||
(mask_blur, "Mask blur"),
|
(mask_blur, "Mask blur"),
|
||||||
|
@ -222,14 +222,18 @@ div.block.gradio-accordion {
|
|||||||
padding: 0.1em 0.75em;
|
padding: 0.1em 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[id$=_seed], [id$=_subseed]{
|
||||||
|
max-width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
[id$=_subseed_show]{
|
[id$=_subseed_show]{
|
||||||
min-width: auto !important;
|
min-width: auto !important;
|
||||||
flex-grow: 0 !important;
|
flex-grow: 0 !important;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
[id$=_subseed_show] label{
|
[id$=_subseed_show] .label-wrap{
|
||||||
margin-bottom: 0.5em;
|
margin: 0 0 0 0.5em;
|
||||||
align-self: end;
|
align-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1028,5 +1032,6 @@ div.accordions{
|
|||||||
|
|
||||||
div.accordions > div.input-accordion.input-accordion-open{
|
div.accordions > div.input-accordion.input-accordion-open{
|
||||||
flex: 1 auto;
|
flex: 1 auto;
|
||||||
|
flex-flow: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user