Added custom field tracking

Added new config files for custom tracked components for txt2img and img2img
Added "Add custom fields..." button
Renamed component IDs to start with "script_"
#28 #31 #32 #33 #34
This commit is contained in:
Zyin055
2023-04-29 00:42:13 -05:00
parent 5c8a867c99
commit fe3176c77f
3 changed files with 383 additions and 217 deletions

2
.gitignore vendored
View File

@@ -2,4 +2,6 @@
scripts/__pycache__
config.json
config-img2img.json
config-img2img-custom-tracked-components.txt
config-txt2img.json
config-txt2img-custom-tracked-components.txt

View File

@@ -3,15 +3,17 @@
//...or do it our more precise way:
onUiUpdate(function() {
//set tooltips
gradioApp().querySelectorAll("#config_presets_open_config_file_button").forEach(el => el.setAttribute("title", "Open the config .json file for manual editing if you want to make changes that way, requires Gradio restart after editing. The txt2img and img2img tabs have separate config files."))
gradioApp().querySelectorAll("#config_preset_save_textbox").forEach(el => el.setAttribute("title", "The name of a new Config Preset that will be added to the dropdown above"))
gradioApp().querySelectorAll("#config_preset_save_button").forEach(el => el.setAttribute("title", "Save selected fields with the new preset name, then restarts the UI. Overwrites existing preset with the same name."))
gradioApp().querySelectorAll("#config_preset_add_button").forEach(el => el.setAttribute("title", "[Config Presets] Create or delete a preset"))
gradioApp().querySelectorAll("#config_preset_cancel_save_button").forEach(el => el.setAttribute("title", "Go back"))
gradioApp().querySelectorAll("#config_preset_trash_button").forEach(el => el.setAttribute("title", "Permanently delete selected preset"))
gradioApp().querySelectorAll("#config_preset_fields_to_save > span").forEach(el => el.setAttribute("title", "Only selected field values will be saved with the preset. Unselected fields will be ignored."))
})
gradioApp().querySelectorAll("#script_config_preset_open_config_file_button").forEach(el => el.setAttribute("title", "Open the config .json file for manual editing if you want to make changes that way, requires Gradio restart after editing. The txt2img and img2img tabs have separate config files."))
gradioApp().querySelectorAll("#script_config_preset_save_textbox").forEach(el => el.setAttribute("title", "The name of a new Config Preset that will be added to the dropdown above"))
gradioApp().querySelectorAll("#script_config_preset_save_button").forEach(el => el.setAttribute("title", "Save selected fields with the new preset name, then restarts the UI. Overwrites existing preset with the same name."))
gradioApp().querySelectorAll("#script_config_preset_add_button").forEach(el => el.setAttribute("title", "[Config Presets] Create or delete a preset"))
gradioApp().querySelectorAll("#script_config_preset_cancel_save_button").forEach(el => el.setAttribute("title", "Go back"))
gradioApp().querySelectorAll("#script_config_preset_trash_button").forEach(el => el.setAttribute("title", "Permanently delete selected preset"))
gradioApp().querySelectorAll("#script_config_preset_fields_to_save > span").forEach(el => el.setAttribute("title", "Only selected field values will be saved with the preset. Unselected fields will be ignored."))
gradioApp().querySelectorAll("#script_config_preset_open_custom_tracked_components_config").forEach(el => el.setAttribute("title", "Open the config file to add new fields to the above list."))
})
/* No longer needed after the bump to Gradio 3.23
//this function called by config_preset_dropdown in config_presets.py
function config_preset_dropdown_change() {
//when Python changes the enable_hr checkbox in config_preset_dropdown_change() it doesn't fire off the change() JS event, so do this manually
@@ -28,7 +30,7 @@ function config_preset_dropdown_change() {
//console.log("e="+e)
}, 200) //50ms is too fast
}
*/
function config_preset_settings_restart_gradio() {
console.log('[Config-Presets] Restarting to apply new config preset...')

View File

@@ -8,22 +8,339 @@ import platform
import subprocess as sp
BASEDIR = scripts.basedir() #C:\Stable Diffusion\extensions\Config-Presets needs to be set in global space to get the extra 'extensions\Config-Presets' path
BASEDIR = scripts.basedir() #C:\path\to\Stable Diffusion\extensions\Config-Presets needs to be set in global space to get the extra 'extensions\Config-Presets' path
CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME = "config-txt2img-custom-tracked-components.txt"
CONFIG_IMG2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME = "config-img2img-custom-tracked-components.txt"
CONFIG_TXT2IMG_FILE_NAME = "config-txt2img.json"
CONFIG_IMG2IMG_FILE_NAME = "config-img2img.json"
#fields_checkboxgroup = None
def load_txt2img_custom_tracked_component_ids() -> list[str]:
txt2img_custom_tracked_components_ids = []
try:
with open(f"{BASEDIR}/{CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME}", "r") as file:
for line in file:
line = line.strip()
if not line.startswith("#") and line != "": # ignore lines that start with # or are empty
txt2img_custom_tracked_components_ids.append(line)
#print(f"Added txt2img custom tracked component: {line}")
except FileNotFoundError:
# config file not found
# First time running the extension or it was deleted, so fill it with default values
txt2img_custom_tracked_components_default_text = """# Put custom txt2img tracked component IDs here. This will allow those fields to be saved as a config preset.
# Lines starting with a # are ignored.
# Component IDs can be found in the HTML (id="...") or in modules/ui.py (elem_id="...").
# Entering an invalid component ID here will cause this extension to error and not load.
# Note that components on the top row of the UI cannot be added here, such as "setting_sd_model_checkpoint", "setting_sd_vae", and "setting_CLIP_stop_at_last_layers".
# Other fields:
#txt2img_prompt
#txt2img_neg_prompt
#txt2img_styles
#txt2img_subseed_show
#txt2img_subseed
#txt2img_subseed_strength
#txt2img_seed_resize_from_w
#txt2img_seed_resize_from_h
#txt2img_tiling
#txt2img_hr_resize_x
#txt2img_hr_resize_y
# Script dropdown:
#script_list
# X/Y/Z plot (script):
#script_txt2txt_xyz_plot_x_type
#script_txt2txt_xyz_plot_y_type
#script_txt2txt_xyz_plot_z_type
#script_txt2txt_xyz_plot_x_values
#script_txt2txt_xyz_plot_y_values
#script_txt2txt_xyz_plot_z_values
# Latent Couple (extension):
#cd_txt2img_divisions
#cd_txt2img_positions
#cd_txt2img_weights
#cd_txt2img_end_at_this_step
"""
write_text_to_file(txt2img_custom_tracked_components_default_text, CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME)
print(f"[Config Presets] txt2img custom tracked components config file not found, created default config at {BASEDIR}/{CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME}")
return txt2img_custom_tracked_components_ids
def load_img2img_custom_tracked_component_ids() -> list[str]:
img2img_custom_tracked_components_ids = []
try:
with open(f"{BASEDIR}/{CONFIG_IMG2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME}", "r") as file:
for line in file:
line = line.strip()
if not line.startswith("#") and line != "": # ignore lines that start with # or are empty
img2img_custom_tracked_components_ids.append(line)
#print(f"Added img2img custom tracked component: {line}")
except FileNotFoundError:
# config file not found
# First time running the extension or it was deleted, so fill it with default values
img2img_custom_tracked_components_ids = """# Put custom img2img tracked component IDs here. This will allow those fields to be saved as a config preset.
# Lines starting with a # are ignored.
# Component IDs can be found in the HTML (id="...") or in modules/ui.py (elem_id="...").
# Entering an invalid component ID here will cause this extension to error and not load.
# Note that components on the top row of the UI cannot be added here, such as "setting_sd_model_checkpoint", "setting_sd_vae", and "setting_CLIP_stop_at_last_layers".
# Other fields:
#img2img_prompt
#img2img_neg_prompt
#img2img_mask_mode
#img2img_mask_blur
#img2img_mask_alpha
#img2img_inpainting_fill
#img2img_inpaint_full_res
#img2img_inpaint_full_res_padding
#resize_mode
#img2img_seed
#img2img_subseed_show
#img2img_subseed
#img2img_subseed_strength
#img2img_seed_resize_from_w
#img2img_seed_resize_from_h
#img2img_restore_faces
#img2img_tiling
#img2img_batch_input_dir
#img2img_batch_output_dir
#img2img_batch_inpaint_mask_dir
# Script dropdown:
#script_list
# X/Y/Z plot (script):
#script_img2txt_xyz_plot_x_type
#script_img2txt_xyz_plot_y_type
#script_img2txt_xyz_plot_z_type
#script_img2txt_xyz_plot_x_values
#script_img2txt_xyz_plot_y_values
#script_img2txt_xyz_plot_z_values
# Loopback (script):
#script_loopback_loops
#script_loopback_final_denoising_strength
# SD upscale (script):
#script_sd_upscale_overlap
#script_sd_upscale_scale_factor
#script_sd_upscale_upscaler_index
# Latent Couple (extension):
#cd_img2img_divisions
#cd_img2img_positions
#cd_img2img_weights
#cd_img2img_end_at_this_step
"""
write_text_to_file(img2img_custom_tracked_components_ids, CONFIG_IMG2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME)
print(f"[Config Presets] img2img custom tracked components config file not found, created default config at {BASEDIR}/{CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME}")
return img2img_custom_tracked_components_ids
def load_txt2img_config_file():
try:
with open(f"{BASEDIR}/{CONFIG_TXT2IMG_FILE_NAME}") as file:
txt2img_config_presets = json.load(file)
except FileNotFoundError:
# txt2img config file not found
# First time running the extension or it was deleted, so fill it with default values
txt2img_config_presets = {
"None": {},
"Low quality ------ 512x512, steps: 10, batch size: 8, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 10,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 8,
# "txt2img_cfg_scale": 7,
},
"Medium quality - 512x512, steps: 15, batch size: 4, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 15,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
# "txt2img_cfg_scale": 7,
},
"High quality ------ 512x512, steps: 20, batch size: 4, DPM++ 2S a Karras": {
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_steps": 20,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
# "txt2img_cfg_scale": 7,
},
"Low quality ------ 768x768, steps: 10, batch size: 8, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 10,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 8,
# "txt2img_cfg_scale": 7,
},
"Medium quality - 768x768, steps: 15, batch size: 4, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 15,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
# "txt2img_cfg_scale": 7,
},
"High quality ------ 768x768, steps: 20, batch size: 4, DPM++ 2S a Karras": {
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_steps": 20,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
# "txt2img_cfg_scale": 7,
},
"High res -------- 1024x1024, steps: 30, batch size: 1, DPM++ 2M Karras, [Upscale by: 2, Denoising: 0.4, Hires steps: 10]": {
"txt2img_steps": 30,
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 2,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.4,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
# "txt2img_cfg_scale": 7,
},
"1080p ----------- 1920x1080, steps: 20, batch size: 1, DPM++ 2S a Karras, [Upscale by: 2.5, Denoising: 0.4, Hires steps: 10]": {
# 2x 960x536, 2.5x 768x432, 3x 640x360
"txt2img_steps": 20,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 2.5,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.4,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
# "txt2img_cfg_scale": 7,
},
"1440p ----------- 2560x1440, steps: 25, batch size: 1, DPM++ 2S a Karras, [Upscale by: 3.3334, Denoising: 0.3, Hires steps: 10]": {
# 2x 1024x720, 2.5x 1024x576, 3.3334x 768x432, 4x 640x360
"txt2img_steps": 25,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 3.3334,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
# "txt2img_cfg_scale": 7,
},
"4k ---------------- 3840x2160, steps: 30, batch size: 1, DPM++ 2S a Karras, [Upscale by: 5, Denoising: 0.3, Hires steps: 15]": {
# 2x 1420x1080, 2.5x 1536x864, 3x 1280x720, 5x 768x432, 6x 640x360
"txt2img_steps": 30,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 5,
"txt2img_hires_steps": 15,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
# "txt2img_cfg_scale": 7,
},
}
write_json_to_file(txt2img_config_presets, CONFIG_TXT2IMG_FILE_NAME)
print(f"[Config Presets] txt2img config file not found, created default config at {BASEDIR}/{CONFIG_TXT2IMG_FILE_NAME}")
return txt2img_config_presets
def load_img2img_config_file():
try:
with open(f"{BASEDIR}/{CONFIG_IMG2IMG_FILE_NAME}") as file:
img2img_config_presets = json.load(file)
except FileNotFoundError:
# img2img config file not found
# First time running the extension or it was deleted, so fill it with default values
img2img_config_presets = {
"None": {},
"Low denoising ------- 512x512, denoising: 0.25, steps: 10, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 10,
"img2img_width": 512,
"img2img_height": 512,
# "img2img_batch_count": 1,
# "img2img_batch_size": 1,
# "img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.25,
},
"Medium denoising -- 512x512, denoising: 0.50, steps: 15, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 15,
"img2img_width": 512,
"img2img_height": 512,
# "img2img_batch_count": 1,
# "img2img_batch_size": 1,
# "img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.50,
},
"High denoising ------- 512x512, denoising: 0.75, steps: 20, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 20,
"img2img_width": 512,
"img2img_height": 512,
# "img2img_batch_count": 1,
# "img2img_batch_size": 1,
# "img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.75,
},
}
write_json_to_file(img2img_config_presets, CONFIG_IMG2IMG_FILE_NAME)
print(f"[Config Presets] img2img config file not found, created default config at {BASEDIR}/{CONFIG_IMG2IMG_FILE_NAME}")
return img2img_config_presets
class Script(scripts.Script):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
#self.txt2img_config_preset_dropdown = None
# Load custom tracked components
txt2img_custom_tracked_components_ids = load_txt2img_custom_tracked_component_ids()
img2img_custom_tracked_components_ids = load_img2img_custom_tracked_component_ids()
# These are the settings from the UI that are saved for each preset
self.txt2img_component_ids = [ # mirrors the config_preset_dropdown.change(output) events and config_preset_dropdown_change()
self.txt2img_component_ids = [
"txt2img_sampling",
"txt2img_steps",
"txt2img_width",
@@ -37,9 +354,10 @@ class Script(scripts.Script):
"txt2img_hires_steps",
"txt2img_denoising_strength",
"txt2img_cfg_scale",
]
self.img2img_component_ids = [ # mirrors the config_preset_dropdown.change(output) events and config_preset_dropdown_change()
self.txt2img_component_ids += txt2img_custom_tracked_components_ids # add the custom tracked components
self.img2img_component_ids = [
"img2img_sampling",
"img2img_steps",
"img2img_width",
@@ -50,200 +368,22 @@ class Script(scripts.Script):
"img2img_denoising_strength",
"img2img_restore_faces",
]
self.img2img_component_ids += img2img_custom_tracked_components_ids # add the custom tracked components
# Mapping between component labels and the actual components in ui.py
self.txt2img_component_map = {k: None for k in self.txt2img_component_ids} # gets filled up in the after_component() method
self.img2img_component_map = {k: None for k in self.img2img_component_ids} # gets filled up in the after_component() method
# Load txt2img and img2img config files
try:
with open(f"{BASEDIR}/{CONFIG_TXT2IMG_FILE_NAME}") as file:
self.txt2img_config_presets = json.load(file)
self.txt2img_config_presets = load_txt2img_config_file()
self.img2img_config_presets = load_img2img_config_file()
# #print("self.config_presets loaded:")
# for preset_name, values_dict in self.txt2img_config_presets.items():
# #print(preset_name,values_dict)
# if "steps" in values_dict.keys():
# print("[ERROR][Config-Presets] Your config.json file is using an outdated format, so the Config Presets dropdown will not work. You need to delete /extensions/Config-Presets/config.json so it can be recreated with the new updated format.")
# break
except FileNotFoundError:
# txt2img config file not found
# First time running the extension or it was deleted, so fill it with default values
self.txt2img_config_presets = {
"None": {},
"Low quality ------ 512x512, steps: 10, batch size: 8, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 10,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 8,
#"txt2img_cfg_scale": 7,
},
"Medium quality - 512x512, steps: 15, batch size: 4, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 15,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
#"txt2img_cfg_scale": 7,
},
"High quality ------ 512x512, steps: 20, batch size: 4, DPM++ 2S a Karras": {
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_steps": 20,
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
#"txt2img_cfg_scale": 7,
},
"Low quality ------ 768x768, steps: 10, batch size: 8, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 10,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 8,
#"txt2img_cfg_scale": 7,
},
"Medium quality - 768x768, steps: 15, batch size: 4, DPM++ 2M Karras": {
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_steps": 15,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
#"txt2img_cfg_scale": 7,
},
"High quality ------ 768x768, steps: 20, batch size: 4, DPM++ 2S a Karras": {
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_steps": 20,
"txt2img_width": 768,
"txt2img_height": 768,
"txt2img_enable_hr": False,
"txt2img_batch_count": 1,
"txt2img_batch_size": 4,
#"txt2img_cfg_scale": 7,
},
"High res -------- 1024x1024, steps: 30, batch size: 1, DPM++ 2M Karras, [Upscale by: 2, Denoising: 0.3, Hires steps: 10]": {
"txt2img_steps": 30,
"txt2img_sampling": "DPM++ 2M Karras",
"txt2img_width": 512,
"txt2img_height": 512,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 2,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
#"txt2img_cfg_scale": 7,
},
"1080p ----------- 1920x1080, steps: 20, batch size: 1, DPM++ 2S a Karras, [Upscale by: 2.5, Denoising: 0.3, Hires steps: 10]": {
#2x 960x536, 2.5x 768x432, 3x 640x360
"txt2img_steps": 20,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 2.5,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
#"txt2img_cfg_scale": 7,
},
"1440p ----------- 2560x1440, steps: 25, batch size: 1, DPM++ 2S a Karras, [Upscale by: 3.3334, Denoising: 0.3, Hires steps: 10]": {
#2x 1024x720, 2.5x 1024x576, 3.3334x 768x432, 4x 640x360
"txt2img_steps": 25,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 3.3334,
"txt2img_hires_steps": 10,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
#"txt2img_cfg_scale": 7,
},
"4k ---------------- 3840x2160, steps: 30, batch size: 1, DPM++ 2S a Karras, [Upscale by: 5, Denoising: 0.3, Hires steps: 15]": {
#2x 1420x1080, 2.5x 1536x864, 3x 1280x720, 5x 768x432, 6x 640x360
"txt2img_steps": 30,
"txt2img_sampling": "DPM++ 2S a Karras",
"txt2img_width": 768,
"txt2img_height": 432,
"txt2img_enable_hr": True,
"txt2img_hr_scale": 5,
"txt2img_hires_steps": 15,
"txt2img_denoising_strength": 0.3,
"txt2img_batch_count": 1,
"txt2img_batch_size": 1,
#"txt2img_cfg_scale": 7,
},
}
write_config_presets_to_file(self.txt2img_config_presets, CONFIG_TXT2IMG_FILE_NAME)
print(f"[Config Presets] txt2img config file not found, created default config at {BASEDIR}/{CONFIG_TXT2IMG_FILE_NAME}")
try:
with open(f"{BASEDIR}/{CONFIG_IMG2IMG_FILE_NAME}") as file:
self.img2img_config_presets = json.load(file)
except FileNotFoundError:
# img2img config file not found
# First time running the extension or it was deleted, so fill it with default values
self.img2img_config_presets = {
"None": {},
"Low denoising ------- 512x512, denoising: 0.25, steps: 10, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 10,
"img2img_width": 512,
"img2img_height": 512,
#"img2img_batch_count": 1,
#"img2img_batch_size": 1,
#"img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.25,
},
"Medium denoising -- 512x512, denoising: 0.50, steps: 15, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 15,
"img2img_width": 512,
"img2img_height": 512,
#"img2img_batch_count": 1,
#"img2img_batch_size": 1,
#"img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.50,
},
"High denoising ------- 512x512, denoising: 0.75, steps: 20, DPM++ 2M Karras": {
"img2img_sampling": "DPM++ 2M Karras",
"img2img_steps": 20,
"img2img_width": 512,
"img2img_height": 512,
#"img2img_batch_count": 1,
#"img2img_batch_size": 1,
#"img2img_cfg_scale": 7,
"img2img_denoising_strength": 0.75,
},
}
write_config_presets_to_file(self.img2img_config_presets, CONFIG_IMG2IMG_FILE_NAME)
print(f"[Config Presets] img2img config file not found, created default config at {BASEDIR}/{CONFIG_IMG2IMG_FILE_NAME}")
def title(self):
return "Config Presets"
def show(self, is_img2img):
#return True
return scripts.AlwaysVisible # hide this script in the Scripts dropdown
def after_component(self, component, **kwargs):
@@ -252,14 +392,17 @@ class Script(scripts.Script):
component_map = None
component_ids = None
config_file_name = None
custom_tracked_components_config_file_name = None
if self.is_txt2img:
component_map = self.txt2img_component_map
component_ids = self.txt2img_component_ids
config_file_name = CONFIG_TXT2IMG_FILE_NAME
custom_tracked_components_config_file_name = CONFIG_TXT2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME
else:
component_map = self.img2img_component_map
component_ids = self.img2img_component_ids
config_file_name = CONFIG_IMG2IMG_FILE_NAME
custom_tracked_components_config_file_name = CONFIG_IMG2IMG_CUSTOM_TRACKED_COMPONENTS_FILE_NAME
#if component.label in self.component_map:
if component.elem_id in component_map:
@@ -277,7 +420,7 @@ class Script(scripts.Script):
for component_name, component in component_map.items():
#print(component_name, component_type)
if component is None:
print(f"[ERROR][Config-Presets] The component '{component_name}' no longer exists in the Web UI. Try updating the Config-Presets extension. This extension will not work until this issue is resolved.")
print(f"[ERROR][Config-Presets] The component '{component_name}' could not be processed. This may be because you are running an outdated version of the Config-Presets extension, or you included a component ID in the custom tracked components config file that does not exist or is an invalid component. This extension will not work until this issue is resolved.")
return
# Mark components with type "index" to be transform
@@ -304,7 +447,7 @@ class Script(scripts.Script):
label="Fields to save",
show_label=True,
interactive=True,
elem_id="config_preset_fields_to_save",
elem_id="script_config_preset_fields_to_save",
).unrender() #we need to define this early on so that it can be used as an input for another function
with gr.Column(min_width=600, elem_id="config_preset_wrapper_txt2img" if self.is_txt2img else "config_preset_wrapper_img2img"): # pushes our stuff onto a new row at 1080p screen resolution
@@ -317,7 +460,7 @@ class Script(scripts.Script):
print(f"[Config-Presets] Changed to: {dropdown_value}")
# update component values with user preset
current_components = dict(zip(component_map.keys(),components_value))
current_components = dict(zip(component_map.keys(), components_value))
#print("Components before:", current_components)
current_components.update(config_preset)
@@ -325,7 +468,7 @@ class Script(scripts.Script):
for component_name, component_value in current_components.items():
#print(component_name, component_value)
if component_name in index_type_components and type(component_value) == int:
current_components[component_name] = component_map[component_name].choices[component_value]
current_components[component_name] = component_map[component_name].choices[component_value]
#print("Components after :", current_components)
@@ -352,12 +495,13 @@ class Script(scripts.Script):
print(traceback.format_exc()) # prints the exception stacktrace
print("[ERROR][CRITICAL][Config-Presets] The Config-Presets extension encountered a fatal error. A component required by this extension no longer exists in the Web UI. This is most likely due to the A1111 Web UI being updated. Try updating the Config-Presets extension. If that doesn't work, please post a bug report at https://github.com/Zyin055/Config-Presets/issues and delete your extensions/Config-Presets folder until an update is published.")
config_preset_dropdown.change(
fn=None,
inputs=[],
outputs=[],
_js="function() { config_preset_dropdown_change() }", # JS is used to update the Hires fix row to show/hide it
)
# No longer needed after the bump to Gradio 3.23
# config_preset_dropdown.change(
# fn=None,
# inputs=[],
# outputs=[],
# _js="function() { config_preset_dropdown_change() }", # JS is used to update the Hires fix row to show/hide it
# )
with gr.Column(scale=8, min_width=100, visible=False) as collapsable_column:
with gr.Row():
with gr.Column(scale=1, min_width=10):
@@ -367,7 +511,7 @@ class Script(scripts.Script):
del config_presets[config_preset_name]
print(f'Config Presets: deleted "{config_preset_name}"')
write_config_presets_to_file(config_presets, config_file_name)
write_json_to_file(config_presets, config_file_name)
preset_keys = list(config_presets.keys())
return gr.Dropdown.update(value=preset_keys[len(preset_keys)-1], choices=preset_keys)
@@ -375,7 +519,7 @@ class Script(scripts.Script):
trash_button = gr.Button(
value="\U0001F5D1",
elem_id="config_preset_trash_button",
elem_id="script_config_preset_trash_button",
)
trash_button.click(
fn=delete_selected_preset,
@@ -401,7 +545,7 @@ class Script(scripts.Script):
open_config_file_button = gr.Button(
value="📂 Open config file...",
elem_id="config_presets_open_config_file_button",
elem_id="script_config_preset_open_config_file_button",
)
open_config_file_button.click(
fn=lambda: open_file(f"{BASEDIR}/{config_file_name}"),
@@ -412,13 +556,13 @@ class Script(scripts.Script):
with gr.Column(scale=2, min_width=50):
cancel_button = gr.Button(
value="Cancel",
elem_id="config_preset_cancel_save_button",
elem_id="script_config_preset_cancel_save_button",
)
with gr.Column(scale=1, min_width=120, visible=True) as add_remove_button_column:
add_remove_button = gr.Button(
value="Add/Remove...",
elem_id="config_preset_add_button",
elem_id="script_config_preset_add_button",
)
with gr.Row() as collapsable_row:
@@ -431,14 +575,14 @@ class Script(scripts.Script):
placeholder="Ex: Low quality",
# value="My Preset",
max_lines=1,
elem_id="config_preset_save_textbox",
elem_id="script_config_preset_save_textbox",
)
with gr.Column(scale=2, min_width=200):
save_button = gr.Button(
# value="Create",
value="💾 Save & Restart",
variant="primary",
elem_id="config_preset_save_button",
elem_id="script_config_preset_save_button",
)
save_button.click(
@@ -484,6 +628,20 @@ class Script(scripts.Script):
with gr.Row():
fields_checkboxgroup.render()
with gr.Row():
with gr.Column(scale=1):
open_custom_tracked_components_config_file_button = gr.Button(
value="📂 Add custom fields...",
elem_id="script_config_preset_open_custom_tracked_components_config",
)
open_custom_tracked_components_config_file_button.click(
fn=lambda: open_file(f"{BASEDIR}/{custom_tracked_components_config_file_name}"),
inputs=[],
outputs=[],
)
with gr.Column(scale=2):
pass
def ui(self, is_img2img):
pass
@@ -530,7 +688,7 @@ def save_config(config_presets, component_map, config_file_name):
#print(f"new_setting_map = {new_setting_map}")
config_presets.update({new_setting_name: new_setting_map})
write_config_presets_to_file(config_presets, config_file_name)
write_json_to_file(config_presets, config_file_name)
# print(f"self.txt2img_config_preset_dropdown.choices before =\n{self.txt2img_config_preset_dropdown.choices}")
# self.txt2img_config_preset_dropdown.choices = list(config_presets.keys())
@@ -549,7 +707,11 @@ def save_config(config_presets, component_map, config_file_name):
return func
def write_config_presets_to_file(config_presets, config_file_name: str):
json_object = json.dumps(config_presets, indent=4)
with open(f"{BASEDIR}/{config_file_name}", "w") as outfile:
outfile.write(json_object)
def write_json_to_file(json_data, file_name: str):
with open(f"{BASEDIR}/{file_name}", "w") as file:
file.write(json.dumps(json_data, indent=4))
def write_text_to_file(text, file_name: str):
with open(f"{BASEDIR}/{file_name}", "w") as file:
file.write(text)