Skip to content

Commit e709afb

Browse files
committed
Merge commit 'e7254746bbfbff45099db44a8d4d25dd6181877d' into 3825-save-hypernet-strength-to-info
2 parents 2c4d203 + e725474 commit e709afb

File tree

9 files changed

+103
-53
lines changed

9 files changed

+103
-53
lines changed

CODEOWNERS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,13 @@
11
* @AUTOMATIC1111
2+
/localizations/ar_AR.json @xmodar @blackneoo
3+
/localizations/de_DE.json @LunixWasTaken
4+
/localizations/es_ES.json @innovaciones
5+
/localizations/fr_FR.json @tumbly
6+
/localizations/it_IT.json @EugenioBuffo
7+
/localizations/ja_JP.json @yuuki76
8+
/localizations/ko_KR.json @36DB
9+
/localizations/pt_BR.json @M-art-ucci
10+
/localizations/ru_RU.json @kabachuha
11+
/localizations/tr_TR.json @camenduru
12+
/localizations/zh_CN.json @dtlnor @bgluminous
13+
/localizations/zh_TW.json @benlisquare
File renamed without changes.

modules/api/api.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from modules.api.models import *
66
from modules.processing import StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img, process_images
77
from modules.sd_samplers import all_samplers
8-
from modules.extras import run_extras
8+
from modules.extras import run_extras, run_pnginfo
99

1010
def upscaler_to_index(name: str):
1111
try:
@@ -32,6 +32,7 @@ def __init__(self, app, queue_lock):
3232
self.app.add_api_route("/sdapi/v1/img2img", self.img2imgapi, methods=["POST"], response_model=ImageToImageResponse)
3333
self.app.add_api_route("/sdapi/v1/extra-single-image", self.extras_single_image_api, methods=["POST"], response_model=ExtrasSingleImageResponse)
3434
self.app.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=ExtrasBatchImagesResponse)
35+
self.app.add_api_route("/sdapi/v1/png-info", self.pnginfoapi, methods=["POST"], response_model=PNGInfoResponse)
3536

3637
def text2imgapi(self, txt2imgreq: StableDiffusionTxt2ImgProcessingAPI):
3738
sampler_index = sampler_to_index(txt2imgreq.sampler_index)
@@ -125,8 +126,13 @@ def prepareFiles(file):
125126

126127
return ExtrasBatchImagesResponse(images=list(map(encode_pil_to_base64, result[0])), html_info=result[1])
127128

128-
def pnginfoapi(self):
129-
raise NotImplementedError
129+
def pnginfoapi(self, req: PNGInfoRequest):
130+
if(not req.image.strip()):
131+
return PNGInfoResponse(info="")
132+
133+
result = run_pnginfo(decode_base64_to_image(req.image.strip()))
134+
135+
return PNGInfoResponse(info=result[1])
130136

131137
def launch(self, server_name, port):
132138
self.app.include_router(self.router)

modules/api/models.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import inspect
2+
from click import prompt
23
from pydantic import BaseModel, Field, create_model
34
from typing import Any, Optional
45
from typing_extensions import Literal
@@ -148,4 +149,10 @@ class ExtrasBatchImagesRequest(ExtrasBaseRequest):
148149
imageList: list[FileData] = Field(title="Images", description="List of images to work on. Must be Base64 strings")
149150

150151
class ExtrasBatchImagesResponse(ExtraBaseResponse):
151-
images: list[str] = Field(title="Images", description="The generated images in base64 format.")
152+
images: list[str] = Field(title="Images", description="The generated images in base64 format.")
153+
154+
class PNGInfoRequest(BaseModel):
155+
image: str = Field(title="Image", description="The base64 encoded PNG image")
156+
157+
class PNGInfoResponse(BaseModel):
158+
info: str = Field(title="Image info", description="A string with all the info the image had")

modules/generation_parameters_copypaste.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from modules.shared import script_path
77
from modules import shared
88
import tempfile
9-
from PIL import Image, PngImagePlugin
9+
from PIL import Image
1010

1111
re_param_code = r'\s*([\w ]+):\s*("(?:\\|\"|[^\"])+"|[^,]*)(?:,|$)'
1212
re_param = re.compile(re_param_code)
@@ -61,6 +61,24 @@ def add_paste_fields(tabname, init_img, fields):
6161
modules.ui.img2img_paste_fields = fields
6262

6363

64+
def integrate_settings_paste_fields(component_dict):
65+
from modules import ui
66+
67+
settings_map = {
68+
'sd_hypernetwork': 'Hypernet',
69+
'CLIP_stop_at_last_layers': 'Clip skip',
70+
'sd_model_checkpoint': 'Model hash',
71+
}
72+
settings_paste_fields = [
73+
(component_dict[k], lambda d, k=k, v=v: ui.apply_setting(k, d.get(v, None)))
74+
for k, v in settings_map.items()
75+
]
76+
77+
for tabname, info in paste_fields.items():
78+
if info["fields"] is not None:
79+
info["fields"] += settings_paste_fields
80+
81+
6482
def create_buttons(tabs_list):
6583
buttons = {}
6684
for tab in tabs_list:
@@ -87,24 +105,22 @@ def run_bind():
87105
)
88106
else:
89107
button.click(
90-
fn=lambda x:x,
108+
fn=lambda x: x,
91109
inputs=[send_image],
92110
outputs=[paste_fields[tab]["init_img"]],
93111
)
94112

95113
if send_generate_info and paste_fields[tab]["fields"] is not None:
96-
paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2']
97-
if shared.opts.send_seed:
98-
paste_field_names += ["Seed"]
99114
if send_generate_info in paste_fields:
115+
paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Face restoration', 'Size-1', 'Size-2'] + (["Seed"] if shared.opts.send_seed else [])
116+
100117
button.click(
101-
fn=lambda *x:x,
102-
inputs=[field for field,name in paste_fields[send_generate_info]["fields"] if name in paste_field_names],
103-
outputs=[field for field,name in paste_fields[tab]["fields"] if name in paste_field_names],
118+
fn=lambda *x: x,
119+
inputs=[field for field, name in paste_fields[send_generate_info]["fields"] if name in paste_field_names],
120+
outputs=[field for field, name in paste_fields[tab]["fields"] if name in paste_field_names],
104121
)
105-
106122
else:
107-
connect_paste(button, [(field, name) for field, name in paste_fields[tab]["fields"] if name in paste_field_names], send_generate_info)
123+
connect_paste(button, paste_fields[tab]["fields"], send_generate_info)
108124

109125
button.click(
110126
fn=None,

modules/processing.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ def infotext(iteration=0, position_in_batch=0):
479479
model_hijack.embedding_db.load_textual_inversion_embeddings()
480480

481481
if p.scripts is not None:
482-
p.scripts.run_alwayson_scripts(p)
482+
p.scripts.process(p)
483483

484484
infotexts = []
485485
output_images = []
@@ -502,7 +502,7 @@ def infotext(iteration=0, position_in_batch=0):
502502
seeds = p.all_seeds[n * p.batch_size:(n + 1) * p.batch_size]
503503
subseeds = p.all_subseeds[n * p.batch_size:(n + 1) * p.batch_size]
504504

505-
if (len(prompts) == 0):
505+
if len(prompts) == 0:
506506
break
507507

508508
with devices.autocast():
@@ -591,7 +591,13 @@ def infotext(iteration=0, position_in_batch=0):
591591
images.save_image(grid, p.outpath_grids, "grid", p.all_seeds[0], p.all_prompts[0], opts.grid_format, info=infotext(), short_filename=not opts.grid_extended_filename, p=p, grid=True)
592592

593593
devices.torch_gc()
594-
return Processed(p, output_images, p.all_seeds[0], infotext() + "".join(["\n\n" + x for x in comments]), subseed=p.all_subseeds[0], all_prompts=p.all_prompts, all_seeds=p.all_seeds, all_subseeds=p.all_subseeds, index_of_first_image=index_of_first_image, infotexts=infotexts)
594+
595+
res = Processed(p, output_images, p.all_seeds[0], infotext() + "".join(["\n\n" + x for x in comments]), subseed=p.all_subseeds[0], all_prompts=p.all_prompts, all_seeds=p.all_seeds, all_subseeds=p.all_subseeds, index_of_first_image=index_of_first_image, infotexts=infotexts)
596+
597+
if p.scripts is not None:
598+
p.scripts.postprocess(p, res)
599+
600+
return res
595601

596602

597603
class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):

modules/scripts.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,16 @@ def run(self, p, *args):
6464
def process(self, p, *args):
6565
"""
6666
This function is called before processing begins for AlwaysVisible scripts.
67-
scripts. You can modify the processing object (p) here, inject hooks, etc.
67+
You can modify the processing object (p) here, inject hooks, etc.
68+
args contains all values returned by components from ui()
69+
"""
70+
71+
pass
72+
73+
def postprocess(self, p, processed, *args):
74+
"""
75+
This function is called after processing ends for AlwaysVisible scripts.
76+
args contains all values returned by components from ui()
6877
"""
6978

7079
pass
@@ -289,13 +298,22 @@ def run(self, p: StableDiffusionProcessing, *args):
289298

290299
return processed
291300

292-
def run_alwayson_scripts(self, p):
301+
def process(self, p):
293302
for script in self.alwayson_scripts:
294303
try:
295304
script_args = p.script_args[script.args_from:script.args_to]
296305
script.process(p, *script_args)
297306
except Exception:
298-
print(f"Error running alwayson script: {script.filename}", file=sys.stderr)
307+
print(f"Error running process: {script.filename}", file=sys.stderr)
308+
print(traceback.format_exc(), file=sys.stderr)
309+
310+
def postprocess(self, p, processed):
311+
for script in self.alwayson_scripts:
312+
try:
313+
script_args = p.script_args[script.args_from:script.args_to]
314+
script.postprocess(p, processed, *script_args)
315+
except Exception:
316+
print(f"Error running postprocess: {script.filename}", file=sys.stderr)
299317
print(traceback.format_exc(), file=sys.stderr)
300318

301319
def reload_sources(self, cache):

modules/ui.py

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ def refresh():
589589
)
590590
return refresh_button
591591

592+
592593
def create_output_panel(tabname, outdir):
593594
def open_folder(f):
594595
if not os.path.exists(f):
@@ -716,6 +717,7 @@ def create_ui(wrap_gradio_gpu_call):
716717
custom_inputs = modules.scripts.scripts_txt2img.setup_ui(is_img2img=False)
717718

718719
txt2img_gallery, generation_info, html_info = create_output_panel("txt2img", opts.outdir_txt2img_samples)
720+
parameters_copypaste.bind_buttons({"txt2img": txt2img_paste}, None, txt2img_prompt)
719721

720722
connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False)
721723
connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True)
@@ -784,7 +786,7 @@ def create_ui(wrap_gradio_gpu_call):
784786
]
785787
)
786788

787-
parameters_copypaste.add_paste_fields("txt2img", None, [
789+
txt2img_paste_fields = [
788790
(txt2img_prompt, "Prompt"),
789791
(txt2img_negative_prompt, "Negative prompt"),
790792
(steps, "Steps"),
@@ -805,7 +807,8 @@ def create_ui(wrap_gradio_gpu_call):
805807
(firstphase_width, "First pass size-1"),
806808
(firstphase_height, "First pass size-2"),
807809
*modules.scripts.scripts_txt2img.infotext_fields
808-
])
810+
]
811+
parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields)
809812

810813
txt2img_preview_params = [
811814
txt2img_prompt,
@@ -893,6 +896,7 @@ def create_ui(wrap_gradio_gpu_call):
893896
custom_inputs = modules.scripts.scripts_img2img.setup_ui(is_img2img=True)
894897

895898
img2img_gallery, generation_info, html_info = create_output_panel("img2img", opts.outdir_img2img_samples)
899+
parameters_copypaste.bind_buttons({"img2img": img2img_paste}, None, img2img_prompt)
896900

897901
connect_reuse_seed(seed, reuse_seed, generation_info, dummy_component, is_subseed=False)
898902
connect_reuse_seed(subseed, reuse_subseed, generation_info, dummy_component, is_subseed=True)
@@ -1038,7 +1042,6 @@ def create_ui(wrap_gradio_gpu_call):
10381042
parameters_copypaste.add_paste_fields("img2img", init_img, img2img_paste_fields)
10391043
parameters_copypaste.add_paste_fields("inpaint", init_img_with_mask, img2img_paste_fields)
10401044

1041-
10421045
with gr.Blocks(analytics_enabled=False) as extras_interface:
10431046
with gr.Row().style(equal_height=False):
10441047
with gr.Column(variant='panel'):
@@ -1050,12 +1053,8 @@ def create_ui(wrap_gradio_gpu_call):
10501053
image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file")
10511054

10521055
with gr.TabItem('Batch from Directory'):
1053-
extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs,
1054-
placeholder="A directory on the same machine where the server is running."
1055-
)
1056-
extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs,
1057-
placeholder="Leave blank to save images to the default path."
1058-
)
1056+
extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.")
1057+
extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.")
10591058
show_extras_results = gr.Checkbox(label='Show result images', value=True)
10601059

10611060
with gr.Tabs(elem_id="extras_resize_mode"):
@@ -1087,7 +1086,6 @@ def create_ui(wrap_gradio_gpu_call):
10871086

10881087
submit = gr.Button('Generate', elem_id="extras_generate", variant='primary')
10891088

1090-
10911089
result_images, html_info_x, html_info = create_output_panel("extras", opts.outdir_extras_samples)
10921090

10931091
submit.click(
@@ -1121,7 +1119,6 @@ def create_ui(wrap_gradio_gpu_call):
11211119
)
11221120
parameters_copypaste.add_paste_fields("extras", extras_image, None)
11231121

1124-
11251122
extras_image.change(
11261123
fn=modules.extras.clear_cache,
11271124
inputs=[], outputs=[]
@@ -1587,9 +1584,6 @@ def request_restart():
15871584
if column is not None:
15881585
column.__exit__()
15891586

1590-
1591-
1592-
15931587
interfaces = [
15941588
(txt2img_interface, "txt2img", "txt2img"),
15951589
(img2img_interface, "img2img", "img2img"),
@@ -1599,10 +1593,6 @@ def request_restart():
15991593
(train_interface, "Train", "ti"),
16001594
]
16011595

1602-
interfaces += script_callbacks.ui_tabs_callback()
1603-
1604-
interfaces += [(settings_interface, "Settings", "settings")]
1605-
16061596
css = ""
16071597

16081598
for cssfile in modules.scripts.list_files_with_name("style.css"):
@@ -1619,6 +1609,9 @@ def request_restart():
16191609
if not cmd_opts.no_progressbar_hiding:
16201610
css += css_hide_progressbar
16211611

1612+
interfaces += script_callbacks.ui_tabs_callback()
1613+
interfaces += [(settings_interface, "Settings", "settings")]
1614+
16221615
with gr.Blocks(css=css, analytics_enabled=False, title="Stable Diffusion") as demo:
16231616
with gr.Row(elem_id="quicksettings"):
16241617
for i, k, item in quicksettings_list:
@@ -1627,6 +1620,9 @@ def request_restart():
16271620

16281621
settings_interface.gradio_ref = demo
16291622

1623+
parameters_copypaste.integrate_settings_paste_fields(component_dict)
1624+
parameters_copypaste.run_bind()
1625+
16301626
with gr.Tabs(elem_id="tabs") as tabs:
16311627
for interface, label, ifid in interfaces:
16321628
with gr.TabItem(label, id=ifid, elem_id='tab_' + ifid):
@@ -1681,16 +1677,6 @@ def modelmerger(*args):
16811677
]
16821678
)
16831679

1684-
1685-
settings_map = {
1686-
'sd_hypernetwork': 'Hypernet',
1687-
'sd_hypernetwork_strength': 'Hypernetwork strength',
1688-
'CLIP_stop_at_last_layers': 'Clip skip',
1689-
'sd_model_checkpoint': 'Model hash',
1690-
}
1691-
1692-
parameters_copypaste.run_bind()
1693-
16941680
ui_config_file = cmd_opts.ui_config_file
16951681
ui_settings = {}
16961682
settings_count = len(ui_settings)
@@ -1709,7 +1695,7 @@ def loadsave(path, x):
17091695
def apply_field(obj, field, condition=None, init_field=None):
17101696
key = path + "/" + field
17111697

1712-
if getattr(obj,'custom_script_source',None) is not None:
1698+
if getattr(obj, 'custom_script_source', None) is not None:
17131699
key = 'customscript/' + obj.custom_script_source + '/' + key
17141700

17151701
if getattr(obj, 'do_not_save_to_config', False):

webui.sh

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,14 @@ then
102102
exit 1
103103
fi
104104

105-
printf "\n%s\n" "${delimiter}"
106-
printf "Clone or update stable-diffusion-webui"
107-
printf "\n%s\n" "${delimiter}"
108105
cd "${install_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/, aborting...\e[0m" "${install_dir}"; exit 1; }
109106
if [[ -d "${clone_dir}" ]]
110107
then
111108
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
112-
"${GIT}" pull
113109
else
110+
printf "\n%s\n" "${delimiter}"
111+
printf "Clone stable-diffusion-webui"
112+
printf "\n%s\n" "${delimiter}"
114113
"${GIT}" clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git "${clone_dir}"
115114
cd "${clone_dir}"/ || { printf "\e[1m\e[31mERROR: Can't cd to %s/%s/, aborting...\e[0m" "${install_dir}" "${clone_dir}"; exit 1; }
116115
fi

0 commit comments

Comments
 (0)