From 4a4647e0dfc812783db7fa993d486b031f098ef8 Mon Sep 17 00:00:00 2001 From: yfszzx Date: Thu, 27 Oct 2022 13:36:11 +0800 Subject: create send to buttons in one module --- modules/generation_parameters_copypaste.py | 86 ++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 4 deletions(-) (limited to 'modules/generation_parameters_copypaste.py') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index f73647da..2b80737a 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -3,13 +3,16 @@ import re import gradio as gr from modules.shared import script_path from modules import shared +import tempfile +from PIL import Image, PngImagePlugin re_param_code = r'\s*([\w ]+):\s*("(?:\\|\"|[^\"])+"|[^,]*)(?:,|$)' re_param = re.compile(re_param_code) re_params = re.compile(r"^(?:" + re_param_code + "){3,}$") re_imagesize = re.compile(r"^(\d+)x(\d+)$") type_of_gr_update = type(gr.update()) - +paste_fields = {} +bind_list = [] def quote(text): if ',' not in str(text): @@ -20,6 +23,81 @@ def quote(text): text = text.replace('"', '\\"') return f'"{text}"' +def image_from_url_text(filedata): + if type(filedata) == dict and filedata["is_file"]: + filename = filedata["name"] + tempdir = os.path.normpath(tempfile.gettempdir()) + normfn = os.path.normpath(filename) + assert normfn.startswith(tempdir), 'trying to open image file not in temporary directory' + + return Image.open(filename) + + if type(filedata) == list: + if len(filedata) == 0: + return None + + filedata = filedata[0] + + if filedata.startswith("data:image/png;base64,"): + filedata = filedata[len("data:image/png;base64,"):] + + filedata = base64.decodebytes(filedata.encode('utf-8')) + image = Image.open(io.BytesIO(filedata)) + return image + +def add_paste_fields(tabname, init_img, fields): + paste_fields[tabname] = {"init_img":init_img, "fields": fields} + +def create_buttons(tabs_list): + buttons = {} + for tab in tabs_list: + buttons[tab] = gr.Button(f"Send to {tab}") + return buttons + +#if send_generate_info is a tab name, mean generate_info comes from the params fields of the tab +def bind_buttons(buttons, send_image, send_generate_info): + bind_list.append([buttons, send_image, send_generate_info]) + +def run_bind(): + for buttons, send_image, send_generate_info in bind_list: + for tab in buttons: + button = buttons[tab] + if send_image and paste_fields[tab]["init_img"]: + if type(send_image) == gr.Gallery: + button.click( + fn=lambda x: image_from_url_text(x), + _js="extract_image_from_gallery", + inputs=[send_image], + outputs=[paste_fields[tab]["init_img"]], + ) + else: + button.click( + fn=lambda x:x, + inputs=[send_image], + outputs=[paste_fields[tab]["init_img"]], + ) + + if send_generate_info and paste_fields[tab]["fields"] is not None: + paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] + if shared.opts.send_seed: + paste_field_names += ["Seed"] + if send_generate_info in paste_fields: + button.click( + fn=lambda *x:x, + inputs=[field for field,name in paste_fields[send_generate_info]["fields"] if name in paste_field_names], + outputs=[field for field,name in paste_fields[tab]["fields"] if name in paste_field_names], + ) + + else: + connect_paste(button, [(field, name) for field, name in paste_fields[tab]["fields"] if name in paste_field_names], send_generate_info) + + button.click( + fn=None, + _js=f"switch_to_{tab}", + inputs=None, + outputs=None, + ) + def parse_generation_parameters(x: str): """parses generation parameters string, the one you see in text field under the picture in UI: ``` @@ -67,8 +145,7 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model return res - -def connect_paste(button, paste_fields, input_comp, js=None): +def connect_paste(button, paste_fields, input_comp): def paste_func(prompt): if not prompt and not shared.cmd_opts.hide_ui_dir_config: filename = os.path.join(script_path, "params.txt") @@ -106,7 +183,8 @@ def connect_paste(button, paste_fields, input_comp, js=None): button.click( fn=paste_func, - _js=js, inputs=[input_comp], outputs=[x[0] for x in paste_fields], ) + + -- cgit v1.2.3 From 3c207ca68483b3406faf519bde2743b578dac222 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sat, 29 Oct 2022 08:42:34 +0300 Subject: add needed imports fr new code in copypaste.py --- modules/generation_parameters_copypaste.py | 9 +++++++++ modules/ui.py | 7 ------- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'modules/generation_parameters_copypaste.py') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 2b80737a..224a17ea 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -1,3 +1,5 @@ +import base64 +import io import os import re import gradio as gr @@ -14,6 +16,7 @@ type_of_gr_update = type(gr.update()) paste_fields = {} bind_list = [] + def quote(text): if ',' not in str(text): return text @@ -23,6 +26,7 @@ def quote(text): text = text.replace('"', '\\"') return f'"{text}"' + def image_from_url_text(filedata): if type(filedata) == dict and filedata["is_file"]: filename = filedata["name"] @@ -45,19 +49,23 @@ def image_from_url_text(filedata): image = Image.open(io.BytesIO(filedata)) return image + def add_paste_fields(tabname, init_img, fields): paste_fields[tabname] = {"init_img":init_img, "fields": fields} + def create_buttons(tabs_list): buttons = {} for tab in tabs_list: buttons[tab] = gr.Button(f"Send to {tab}") return buttons + #if send_generate_info is a tab name, mean generate_info comes from the params fields of the tab def bind_buttons(buttons, send_image, send_generate_info): bind_list.append([buttons, send_image, send_generate_info]) + def run_bind(): for buttons, send_image, send_generate_info in bind_list: for tab in buttons: @@ -98,6 +106,7 @@ def run_bind(): outputs=None, ) + def parse_generation_parameters(x: str): """parses generation parameters string, the one you see in text field under the picture in UI: ``` diff --git a/modules/ui.py b/modules/ui.py index 46657dd4..280910d0 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -1,6 +1,4 @@ -import base64 import html -import io import json import math import mimetypes @@ -18,13 +16,8 @@ import gradio as gr import gradio.routes import gradio.utils import numpy as np -import piexif -import torch from PIL import Image, PngImagePlugin -import gradio as gr -import gradio.utils -import gradio.routes from modules import sd_hijack, sd_models, localization, script_callbacks from modules.paths import script_path -- cgit v1.2.3 From 2922d8144f677ea3c37189a2b2e3c3d3ff6d3916 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sat, 29 Oct 2022 09:01:04 +0300 Subject: make existing image browser extension not break --- modules/generation_parameters_copypaste.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'modules/generation_parameters_copypaste.py') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 224a17ea..d590e9ee 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -51,7 +51,14 @@ def image_from_url_text(filedata): def add_paste_fields(tabname, init_img, fields): - paste_fields[tabname] = {"init_img":init_img, "fields": fields} + paste_fields[tabname] = {"init_img": init_img, "fields": fields} + + # backwards compatibility for existing extensions + import modules.ui + if tabname == 'txt2img': + modules.ui.txt2img_paste_fields = fields + elif tabname == 'img2img': + modules.ui.img2img_paste_fields = fields def create_buttons(tabs_list): @@ -61,7 +68,7 @@ def create_buttons(tabs_list): return buttons -#if send_generate_info is a tab name, mean generate_info comes from the params fields of the tab +#if send_generate_info is a tab name, mean generate_info comes from the params fields of the tab def bind_buttons(buttons, send_image, send_generate_info): bind_list.append([buttons, send_image, send_generate_info]) @@ -84,12 +91,12 @@ def run_bind(): inputs=[send_image], outputs=[paste_fields[tab]["init_img"]], ) - + if send_generate_info and paste_fields[tab]["fields"] is not None: paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] if shared.opts.send_seed: paste_field_names += ["Seed"] - if send_generate_info in paste_fields: + if send_generate_info in paste_fields: button.click( fn=lambda *x:x, inputs=[field for field,name in paste_fields[send_generate_info]["fields"] if name in paste_field_names], @@ -154,7 +161,8 @@ Steps: 20, Sampler: Euler a, CFG scale: 7, Seed: 965400086, Size: 512x512, Model return res -def connect_paste(button, paste_fields, input_comp): + +def connect_paste(button, paste_fields, input_comp, jsfunc=None): def paste_func(prompt): if not prompt and not shared.cmd_opts.hide_ui_dir_config: filename = os.path.join(script_path, "params.txt") @@ -192,6 +200,7 @@ def connect_paste(button, paste_fields, input_comp): button.click( fn=paste_func, + _js=jsfunc, inputs=[input_comp], outputs=[x[0] for x in paste_fields], ) -- cgit v1.2.3 From 35c45df28b303a05d56a13cb56d4046f08cf8c25 Mon Sep 17 00:00:00 2001 From: AUTOMATIC <16777216c@gmail.com> Date: Sat, 29 Oct 2022 10:56:19 +0300 Subject: fix broken ↙ button, fix field paste ignoring most of useful fields for for #3768 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/generation_parameters_copypaste.py | 36 ++++++++++++++++++------- modules/ui.py | 43 +++++++++++------------------- 2 files changed, 41 insertions(+), 38 deletions(-) (limited to 'modules/generation_parameters_copypaste.py') diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index d590e9ee..bbaad42e 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -6,7 +6,7 @@ import gradio as gr from modules.shared import script_path from modules import shared import tempfile -from PIL import Image, PngImagePlugin +from PIL import Image re_param_code = r'\s*([\w ]+):\s*("(?:\\|\"|[^\"])+"|[^,]*)(?:,|$)' re_param = re.compile(re_param_code) @@ -61,6 +61,24 @@ def add_paste_fields(tabname, init_img, fields): modules.ui.img2img_paste_fields = fields +def integrate_settings_paste_fields(component_dict): + from modules import ui + + settings_map = { + 'sd_hypernetwork': 'Hypernet', + 'CLIP_stop_at_last_layers': 'Clip skip', + 'sd_model_checkpoint': 'Model hash', + } + settings_paste_fields = [ + (component_dict[k], lambda d, k=k, v=v: ui.apply_setting(k, d.get(v, None))) + for k, v in settings_map.items() + ] + + for tabname, info in paste_fields.items(): + if info["fields"] is not None: + info["fields"] += settings_paste_fields + + def create_buttons(tabs_list): buttons = {} for tab in tabs_list: @@ -87,24 +105,22 @@ def run_bind(): ) else: button.click( - fn=lambda x:x, + fn=lambda x: x, inputs=[send_image], outputs=[paste_fields[tab]["init_img"]], ) if send_generate_info and paste_fields[tab]["fields"] is not None: - paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] - if shared.opts.send_seed: - paste_field_names += ["Seed"] if send_generate_info in paste_fields: + paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] + (["Seed"] if shared.opts.send_seed else []) + button.click( - fn=lambda *x:x, - inputs=[field for field,name in paste_fields[send_generate_info]["fields"] if name in paste_field_names], - outputs=[field for field,name in paste_fields[tab]["fields"] if name in paste_field_names], + fn=lambda *x: x, + inputs=[field for field, name in paste_fields[send_generate_info]["fields"] if name in paste_field_names], + outputs=[field for field, name in paste_fields[tab]["fields"] if name in paste_field_names], ) - else: - connect_paste(button, [(field, name) for field, name in paste_fields[tab]["fields"] if name in paste_field_names], send_generate_info) + connect_paste(button, paste_fields[tab]["fields"], send_generate_info) button.click( fn=None, diff --git a/modules/ui.py b/modules/ui.py index 3c34eca0..5055ca64 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -589,6 +589,7 @@ def create_refresh_button(refresh_component, refresh_method, refreshed_args, ele ) return refresh_button + def create_output_panel(tabname, outdir): def open_folder(f): if not os.path.exists(f): @@ -716,6 +717,7 @@ def create_ui(wrap_gradio_gpu_call): custom_inputs = modules.scripts.scripts_txt2img.setup_ui(is_img2img=False) txt2img_gallery, generation_info, html_info = create_output_panel("txt2img", opts.outdir_txt2img_samples) + parameters_copypaste.bind_buttons({"txt2img": txt2img_paste}, None, txt2img_prompt) 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) @@ -784,7 +786,7 @@ def create_ui(wrap_gradio_gpu_call): ] ) - parameters_copypaste.add_paste_fields("txt2img", None, [ + txt2img_paste_fields = [ (txt2img_prompt, "Prompt"), (txt2img_negative_prompt, "Negative prompt"), (steps, "Steps"), @@ -805,7 +807,8 @@ def create_ui(wrap_gradio_gpu_call): (firstphase_width, "First pass size-1"), (firstphase_height, "First pass size-2"), *modules.scripts.scripts_txt2img.infotext_fields - ]) + ] + parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields) txt2img_preview_params = [ txt2img_prompt, @@ -893,6 +896,7 @@ def create_ui(wrap_gradio_gpu_call): custom_inputs = modules.scripts.scripts_img2img.setup_ui(is_img2img=True) img2img_gallery, generation_info, html_info = create_output_panel("img2img", opts.outdir_img2img_samples) + parameters_copypaste.bind_buttons({"img2img": img2img_paste}, None, img2img_prompt) 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) @@ -1038,7 +1042,6 @@ def create_ui(wrap_gradio_gpu_call): parameters_copypaste.add_paste_fields("img2img", init_img, img2img_paste_fields) parameters_copypaste.add_paste_fields("inpaint", init_img_with_mask, img2img_paste_fields) - with gr.Blocks(analytics_enabled=False) as extras_interface: with gr.Row().style(equal_height=False): with gr.Column(variant='panel'): @@ -1050,12 +1053,8 @@ def create_ui(wrap_gradio_gpu_call): image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file") with gr.TabItem('Batch from Directory'): - extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, - placeholder="A directory on the same machine where the server is running." - ) - extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, - placeholder="Leave blank to save images to the default path." - ) + extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.") + extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.") show_extras_results = gr.Checkbox(label='Show result images', value=True) with gr.Tabs(elem_id="extras_resize_mode"): @@ -1087,7 +1086,6 @@ def create_ui(wrap_gradio_gpu_call): submit = gr.Button('Generate', elem_id="extras_generate", variant='primary') - result_images, html_info_x, html_info = create_output_panel("extras", opts.outdir_extras_samples) submit.click( @@ -1121,7 +1119,6 @@ def create_ui(wrap_gradio_gpu_call): ) parameters_copypaste.add_paste_fields("extras", extras_image, None) - extras_image.change( fn=modules.extras.clear_cache, inputs=[], outputs=[] @@ -1587,9 +1584,6 @@ def create_ui(wrap_gradio_gpu_call): if column is not None: column.__exit__() - - - interfaces = [ (txt2img_interface, "txt2img", "txt2img"), (img2img_interface, "img2img", "img2img"), @@ -1599,10 +1593,6 @@ def create_ui(wrap_gradio_gpu_call): (train_interface, "Train", "ti"), ] - interfaces += script_callbacks.ui_tabs_callback() - - interfaces += [(settings_interface, "Settings", "settings")] - css = "" for cssfile in modules.scripts.list_files_with_name("style.css"): @@ -1619,6 +1609,9 @@ def create_ui(wrap_gradio_gpu_call): if not cmd_opts.no_progressbar_hiding: css += css_hide_progressbar + interfaces += script_callbacks.ui_tabs_callback() + interfaces += [(settings_interface, "Settings", "settings")] + with gr.Blocks(css=css, analytics_enabled=False, title="Stable Diffusion") as demo: with gr.Row(elem_id="quicksettings"): for i, k, item in quicksettings_list: @@ -1627,6 +1620,9 @@ def create_ui(wrap_gradio_gpu_call): settings_interface.gradio_ref = demo + parameters_copypaste.integrate_settings_paste_fields(component_dict) + parameters_copypaste.run_bind() + with gr.Tabs(elem_id="tabs") as tabs: for interface, label, ifid in interfaces: with gr.TabItem(label, id=ifid, elem_id='tab_' + ifid): @@ -1681,15 +1677,6 @@ def create_ui(wrap_gradio_gpu_call): ] ) - - settings_map = { - 'sd_hypernetwork': 'Hypernet', - 'CLIP_stop_at_last_layers': 'Clip skip', - 'sd_model_checkpoint': 'Model hash', - } - - parameters_copypaste.run_bind() - ui_config_file = cmd_opts.ui_config_file ui_settings = {} settings_count = len(ui_settings) @@ -1708,7 +1695,7 @@ def create_ui(wrap_gradio_gpu_call): def apply_field(obj, field, condition=None, init_field=None): key = path + "/" + field - if getattr(obj,'custom_script_source',None) is not None: + if getattr(obj, 'custom_script_source', None) is not None: key = 'customscript/' + obj.custom_script_source + '/' + key if getattr(obj, 'do_not_save_to_config', False): -- cgit v1.2.3