img2img tab support

and code cleanup
This commit is contained in:
Zyin055
2022-12-20 22:05:47 -06:00
parent 6d6c466071
commit c84d4b61a0
2 changed files with 58 additions and 88 deletions

View File

@@ -1,12 +1,12 @@
//add tooltip by piggybacking off of javascript/hints.js //add tooltip by piggybacking off of javascript/hints.js
//titles["Edit..."] = "[Config Presets] open config.json" //titles["Add/Remove..."] = "[Config Presets] Add or remove a preset"
//or do it our more precise way //or do it our more precise way
onUiUpdate(function() { onUiUpdate(function() {
//set tooltips //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")) 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"))
gradioApp().querySelectorAll("#config_preset_save_textbox").forEach(el => el.setAttribute("title", "The label that will be displayed in the dropdown to the left")) gradioApp().querySelectorAll("#config_preset_save_textbox").forEach(el => el.setAttribute("title", "The label that will be displayed in the dropdown to the left"))
gradioApp().querySelectorAll("#config_preset_save_button").forEach(el => el.setAttribute("title", "Saves current settings with the new preset name")) gradioApp().querySelectorAll("#config_preset_save_button").forEach(el => el.setAttribute("title", "Saves current settings with the new preset name. This will save: Steps, Sampler, Width/Height, Highres fix, Firstpass width/height, Denoising strength, Batch size, CFG Scale."))
gradioApp().querySelectorAll("#config_preset_add_button").forEach(el => el.setAttribute("title", "[Config Presets] Add or remove a preset")) gradioApp().querySelectorAll("#config_preset_add_button").forEach(el => el.setAttribute("title", "[Config Presets] Add or remove a preset"))
gradioApp().querySelectorAll("#config_preset_cancel_save_button").forEach(el => el.setAttribute("title", "Go back")) 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_trash_button").forEach(el => el.setAttribute("title", "Permanently delete selected preset"))
@@ -25,11 +25,4 @@ function config_preset_dropdown_change() {
e.initEvent("change", true, false) e.initEvent("change", true, false)
highresCheckbox.dispatchEvent(e) highresCheckbox.dispatchEvent(e)
}, 200) //50ms is too fast }, 200) //50ms is too fast
}
function config_presets_add_new_preset() {
console.log("config_presets_add_new_preset()")
const temp = prompt("name?")
console.log("returning temp="+temp)
return temp
} }

View File

@@ -1,5 +1,3 @@
import time
import modules.scripts as scripts import modules.scripts as scripts
import modules.sd_samplers import modules.sd_samplers
import gradio as gr import gradio as gr
@@ -7,41 +5,23 @@ import json
import os import os
import platform import platform
import subprocess as sp import subprocess as sp
import logging
from pprint import pprint as pp
#logging.basicConfig(level=logging.DEBUG)
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:\Stable Diffusion\extensions\Config-Presets needs to be set in global space to get the extra 'extensions\Config-Presets' path
def write_config_presets_to_file(config_presets):
json_object = json.dumps(config_presets, indent=4)
with open(f"{basedir}/config.json", "w") as outfile:
outfile.write(json_object)
class Script(scripts.Script): class Script(scripts.Script):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.config_file_name = "config.json"
#self.basedir = scripts.basedir() #C:\Stable Diffusion #use at global instead to get the extra 'extensions\Config-Presets' path. # These are the settings from the UI that are saved for each preset
# First value is the component label, second value is the internal name which is kept for legacy version support
# self.component_labels = [
# "Sampling Steps",
# "Sampling method",
# "Width",
# "Height",
# "Highres. fix",
# "Firstpass width",
# "Firstpass height",
# "Denoising strength",
# "Batch count",
# "Batch size",
# "CFG Scale",
# ]
self.component_labels = { self.component_labels = {
"Sampling Steps": "steps", "Sampling Steps": "steps",
"Sampling method": "sampler_index", "Sampling method": "sampler_index",
@@ -55,14 +35,19 @@ class Script(scripts.Script):
"Batch size": "batch_size", "Batch size": "batch_size",
"CFG Scale": "cfg_scale", "CFG Scale": "cfg_scale",
} }
self.component_map = {k: None for k in self.component_labels} # gets filled up in after_component() # These are the components that are NOT found in the img2img tab
#print(f"init self.component_map={self.component_map}") self.components_not_in_img2img_tab = [
self.settings_file = "config.json" "Highres. fix",
self.save_as = gr.Text(render=False) "Firstpass width",
"Firstpass height",
]
# Load config from file # Mapping between component labels and the actual components in ui.py
self.component_map = {k: None for k in self.component_labels} # gets filled up in the after_component() method
# Load config file
try: try:
with open(f"{basedir}/config.json") as file: with open(f"{basedir}/{self.config_file_name}") as file:
self.config_presets = json.load(file) self.config_presets = json.load(file)
except FileNotFoundError: except FileNotFoundError:
# Config file not found # Config file not found
@@ -124,8 +109,17 @@ class Script(scripts.Script):
"cfg_scale": 7 "cfg_scale": 7
} }
} }
write_config_presets_to_file()
print(f"Config Presets: Config file not found, created default config at {basedir}/config.json") self.write_config_presets_to_file()
print(f"Config Presets: Config file not found, created default config at {basedir}/{self.config_file_name}")
def write_config_presets_to_file(self):
json_object = json.dumps(self.config_presets, indent=4)
with open(f"{basedir}/{self.config_file_name}", "w") as outfile:
outfile.write(json_object)
def title(self): def title(self):
@@ -137,7 +131,6 @@ class Script(scripts.Script):
def after_component(self, component, **kwargs): def after_component(self, component, **kwargs):
if component.label in self.component_map: if component.label in self.component_map:
self.component_map[component.label] = component self.component_map[component.label] = component
#print(f"DEBUG: found component: {component} {component.label}") #print(f"DEBUG: found component: {component} {component.label}")
@@ -155,7 +148,6 @@ class Script(scripts.Script):
with gr.Row(): with gr.Row():
with gr.Column(scale=8, min_width=100) as dropdown_column: with gr.Column(scale=8, min_width=100) as dropdown_column:
def config_preset_dropdown_change(dropdown_value): def config_preset_dropdown_change(dropdown_value):
#print(f"config_preset_dropdown_change(dropdown_value={dropdown_value})")
config_preset = self.config_presets[dropdown_value] config_preset = self.config_presets[dropdown_value]
print(f"Config Presets: changed to {dropdown_value}") print(f"Config Presets: changed to {dropdown_value}")
@@ -196,7 +188,9 @@ class Script(scripts.Script):
elem_id="config_preset_dropdown", elem_id="config_preset_dropdown",
) )
config_preset_dropdown.style(container=False) #set to True to give it a white box to sit in config_preset_dropdown.style(container=False) #set to True to give it a white box to sit in
if self.component_map["Highres. fix"]:
if self.is_txt2img:
#if self.component_map["Highres. fix"]:
config_preset_dropdown.change( config_preset_dropdown.change(
fn=config_preset_dropdown_change, fn=config_preset_dropdown_change,
show_progress=False, show_progress=False,
@@ -239,18 +233,16 @@ class Script(scripts.Script):
outputs=[], outputs=[],
_js="function() { config_preset_dropdown_change() }", # JS is used to update the Highres fix row to show/hide it _js="function() { config_preset_dropdown_change() }", # JS is used to update the Highres fix row to show/hide it
) )
with gr.Column(scale=15, min_width=100, visible=False) as save_column: with gr.Column(scale=15, min_width=100, visible=False) as collapsable_column:
with gr.Row(): with gr.Row():
with gr.Column(scale=1, min_width=10): with gr.Column(scale=1, min_width=10):
def delete_selected_preset(config_preset_name): def delete_selected_preset(config_preset_name):
if config_preset_name in self.config_presets.keys(): if config_preset_name in self.config_presets.keys():
del self.config_presets[config_preset_name] del self.config_presets[config_preset_name]
print(f'Config Presets: deleted "{config_preset_name}"') print(f'Config Presets: deleted "{config_preset_name}"')
#print(f"new self.config_presets={self.config_presets}")
write_config_presets_to_file(self.config_presets) self.write_config_presets_to_file()
preset_keys = list(self.config_presets.keys()) preset_keys = list(self.config_presets.keys())
return gr.Dropdown.update(value=preset_keys[len(preset_keys)-1], choices=preset_keys) return gr.Dropdown.update(value=preset_keys[len(preset_keys)-1], choices=preset_keys)
@@ -301,13 +293,12 @@ class Script(scripts.Script):
else: else:
sp.Popen(["xdg-open", path]) sp.Popen(["xdg-open", path])
open_config_file_button = gr.Button( # tooltip is set in javascript/config_presets.js open_config_file_button = gr.Button(
value="Open...", value="Open...",
elem_id="config_presets_open_config_file_button", elem_id="config_presets_open_config_file_button",
# visible=False,
) )
open_config_file_button.click( open_config_file_button.click(
fn=lambda: open_file(f"{basedir}/config.json"), fn=lambda: open_file(f"{basedir}/{self.config_file_name}"),
inputs=[], inputs=[],
outputs=[], outputs=[],
) )
@@ -318,7 +309,7 @@ class Script(scripts.Script):
elem_id="config_preset_cancel_save_button", elem_id="config_preset_cancel_save_button",
) )
with gr.Column(scale=1, min_width=120, visible=True) as add_column: with gr.Column(scale=1, min_width=120, visible=True) as add_remove_button_column:
add_remove_button = gr.Button( add_remove_button = gr.Button(
value="Add/Remove...", value="Add/Remove...",
elem_id="config_preset_add_button", elem_id="config_preset_add_button",
@@ -339,68 +330,53 @@ class Script(scripts.Script):
add_remove_button.click( add_remove_button.click(
fn=add_remove_button_click, fn=add_remove_button_click,
inputs=[], inputs=[],
outputs=[save_column, add_column], outputs=[collapsable_column, add_remove_button_column],
) )
save_button.click( save_button.click(
fn=save_button_click, fn=save_button_click,
inputs=[save_textbox], inputs=[save_textbox],
outputs=[add_column, save_column], outputs=[add_remove_button_column, collapsable_column],
) )
cancel_button.click( cancel_button.click(
fn=cancel_button_click, fn=cancel_button_click,
inputs=[], inputs=[],
outputs=[add_column, save_column], outputs=[add_remove_button_column, collapsable_column],
) )
#with gr.Column(scale=1, min_width=30) as edit_column:
def ui(self, is_img2img): def ui(self, is_img2img):
pass pass
def run(self, p, *args): def run(self, p, *args):
pass pass
# Save the current values on the UI to a new entry in the config file
# Gerschel came up with the idea for this code trick
def save_config(self): def save_config(self):
"""
Helper function to utilize closure
"""
# closure keeps path in memory, it's a hack to get around how click or change expects values to be formatted # closure keeps path in memory, it's a hack to get around how click or change expects values to be formatted
def func(new_setting_name, *new_setting): def func(new_setting_name, *new_setting):
""" #print(f"save_config() func() new_setting_name={new_setting_name} *new_setting={new_setting}")
Formats setting and overwrites file #print(f"new_setting_name={new_setting_name}")
input: setting_name is text autoformatted from clicks input
new_settings is a tuple (by using packing) of formatted text, outputs from
click method must be in same order of labels
"""
print(f"save_config() in python")
#print(f"save_config() func() setting_name={setting_name} *new_setting={new_setting}")
if new_setting_name == "": if new_setting_name == "":
return gr.Dropdown.update(), "" # do nothing return gr.Dropdown.update(), "" # do nothing if no label entered in textbox
# Format new_setting from tuple of values, and map them to their label
# Using presence of hires button to determine if we are img2img or txt2img
# if self.is_txt2img:
# new_setting = {k:new_setting[i] if k != "Sampling method" else modules.sd_samplers.samplers[new_setting[i]].name for i, k in enumerate(self.component_labels) if self.component_map[k] is not None}
# else:
# new_setting = {k:new_setting[i] if k != "Sampling method" else modules.sd_samplers.samplers_for_img2img[new_setting[i]].name for i, k in enumerate(self.component_labels) if self.component_map[k] is not None}
new_setting_map = {} new_setting_map = {}
j = 0
for i, k in enumerate(self.component_labels): for i, k in enumerate(self.component_labels):
#print(f"i={i}, k={k}") # i=1,2,3... k="Sampling Steps", "Sampling methods", etc #print(f"i={i}, j={j} k={k}") # i=1,2,3... k="Sampling Steps", "Sampling methods", ...
if self.is_img2img and k in self.components_not_in_img2img_tab:
#if we're in the img2img tab, skip Highres. fix, Firstpass width, Firstpass height
#print(f"{k} is not in the img2img tab, skipping")
continue
if self.component_map[k] is not None: if self.component_map[k] is not None:
internal_name = self.component_labels[k] internal_name = self.component_labels[k]
new_value = new_setting[i] new_value = new_setting[j]
#print(f"internal_name={internal_name}, new_value={new_value}") #print(f"internal_name={internal_name}, new_value={new_value}")
if k != "Sampling method": if k != "Sampling method":
#pass
new_setting_map[internal_name] = new_value new_setting_map[internal_name] = new_value
else: else:
if self.is_txt2img: if self.is_txt2img:
@@ -408,13 +384,14 @@ class Script(scripts.Script):
else: else:
new_setting_map[internal_name] = modules.sd_samplers.samplers_for_img2img[new_value].name new_setting_map[internal_name] = modules.sd_samplers.samplers_for_img2img[new_value].name
print(f"new_setting_name={new_setting_name}") j += 1
self.config_presets.update({new_setting_name: new_setting_map}) self.config_presets.update({new_setting_name: new_setting_map})
write_config_presets_to_file(self.config_presets) self.write_config_presets_to_file()
#print(f"new dropdown values: {list(self.config_presets.keys())}") #print(f"new dropdown values: {list(self.config_presets.keys())}")
# update the dropdown with the new config preset, clear the 'new preset name' textbox
return gr.Dropdown.update(value=new_setting_name, choices=list(self.config_presets.keys())), "" return gr.Dropdown.update(value=new_setting_name, choices=list(self.config_presets.keys())), ""
return func return func