Skip to content

Commit afabf28

Browse files
author
legionfu
committed
* ControlNet模型支持模糊匹配。
* 如本地没有ControlNet模型,会提供下载链接。 * 缺失插件提示。 * 插件增加中英文切换。 * 插件导入提示优化。 * 参数保存逻辑优化。
1 parent 492114f commit afabf28

File tree

6 files changed

+342
-159
lines changed

6 files changed

+342
-159
lines changed

ChangeLog.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,20 @@
33
### Features:
44
* UI组件增加elem_id。
55
* flow文件导出时,支持自定义名称。
6+
* ControlNet模型支持模糊匹配。
7+
* 如本地没有ControlNet模型,会提供下载链接。
8+
* 缺失插件提示。
9+
* 插件增加中英文切换。
610

711
### Bug Fixes:
812
* 图片组件保存功能优化,支持所有带elem_id的图片组件。
9-
因为gradio组件bug影响,目前暂时不支持不带elem_id的组件保存功能。目前新版本似乎已经修复,但秋叶启动器的gradio版本似乎还是旧版?
13+
因为gradio组件bug影响,目前暂时不支持不带elem_id的组件保存功能。
14+
目前新版本似乎已经修复,但秋叶启动器的gradio版本似乎还是旧版?待跟进。
1015
issue链接: https://github.com/gradio-app/gradio/issues/5548
1116
* refiner参数保存bug修复。
1217
* 插件含tab的组件保存编号错误bug修复。
18+
* 插件导入提示优化。
19+
* 参数保存逻辑优化。
1320

1421
## 2.1.1
1522

javascript/state.core.js

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ state.core = (function () {
142142
}
143143

144144
let img_elem_keys=[];
145+
let ext_list=[];
145146

146147
function get_imgs_elem_key(){
147148

@@ -161,10 +162,16 @@ state.core = (function () {
161162
IMAGES_WITHOUT_PREFIX[key] = key
162163
});
163164

165+
fetch('/lightdiffusionflow/local/get_ext_list')
166+
.then(response => response.json())
167+
.then(data => {
168+
ext_list = data.split(",")
169+
});
170+
164171
// 等上面的组件ID同步过来后 再加载其他配置
165172
fetch('/lightdiffusionflow/local/config.json?_=' + (+new Date()))
166173
.then(response => response.json())
167-
.then(config => {
174+
.then(config => {
168175
try {
169176
store = new state.Store();
170177
store.clearAll();
@@ -602,6 +609,13 @@ state.core = (function () {
602609
}
603610
}
604611

612+
for (let key in stored_config){
613+
if(key.indexOf("allow-preview") !== -1 && key.indexOf("ext-control-net") !== -1)
614+
{
615+
stored_config[key] = "false"
616+
}
617+
}
618+
605619
var checkTime = function (i) {
606620
if (i < 10) { i = "0" + i; }
607621
return i;
@@ -622,6 +636,8 @@ state.core = (function () {
622636
filename += ".flow";
623637
}
624638
if(filename != ".flow"){
639+
// const handle = window.showDirectoryPicker();
640+
// console.log(handle)
625641
state.utils.saveFile(filename, stored_config);
626642
}
627643

@@ -632,14 +648,16 @@ state.core = (function () {
632648
},
633649

634650
handleLightDiffusionFlow: function (fileInput){
635-
actions.output_log("Start parsing settings...")
651+
actions.preset_output_log("start")
652+
//actions.output_log("<hr style='margin-top:10px;margin-bottom:10px'>Start parsing settings...")
636653
console.log(fileInput)
637654
let temp_fileInput = undefined
638655
try{temp_fileInput = fileInput[0]} catch(error){}
639656
if ( !temp_fileInput ) {temp_fileInput = fileInput}
640657
if ( !temp_fileInput ) {
641658
//alert('Please select a JSON file!');
642-
actions.output_log("Please select a valid lightdiffusionflow or image file!")
659+
actions.preset_output_log("invalid")
660+
//actions.output_log("Please select a valid lightdiffusionflow or image file!")
643661
return;
644662
}
645663

@@ -696,16 +714,44 @@ state.core = (function () {
696714
},
697715
importLightDiffusionFlow: function (inputData){
698716

717+
699718
forEachElement_WithoutTabs(IMAGES_WITHOUT_PREFIX, (image_id) => {
700719
state.utils.clearImage(getElement(image_id));
701720
});
702721

703722
let json_obj = {}
704723
try { json_obj = JSON.parse(inputData) } catch (error) {
705-
actions.output_log("Please select a valid lightdiffusionflow or image file!")
724+
actions.preset_output_log("invalid")
725+
//actions.output_log("Please select a valid lightdiffusionflow or image file!")
706726
return;
707727
}
708728

729+
// 缺少的插件
730+
console.log(ext_list)
731+
missing_ext_list = []
732+
for (let key in json_obj){
733+
ext_name = key.match(/ext-(\S+)-(txt2img|img2img)/)
734+
console.log(key)
735+
if(ext_name != null){
736+
ext_name = ext_name[1]
737+
console.log(ext_name)
738+
if(ext_list.indexOf(ext_name) === -1){
739+
if(missing_ext_list.indexOf(ext_name) === -1){
740+
missing_ext_list.push(ext_name)
741+
}
742+
}
743+
}
744+
}
745+
746+
if(missing_ext_list.length > 0){
747+
// error_str = "Error: <b style='color:Red;'>Found missing extensions.</b></p>"
748+
// for (ext of missing_ext_list){
749+
// error_str+="<p>- <b style='color:Red;'>"+ext+"</b></p>"
750+
// }
751+
// actions.output_log(error_str)
752+
actions.preset_output_log("missing_exts","",missing_ext_list.join(';'))
753+
}
754+
709755
forEachElement_WithoutTabs(IMAGES_WITHOUT_PREFIX, (image_id) => {
710756
json_obj[image_id] = ""
711757
});
@@ -718,10 +764,10 @@ state.core = (function () {
718764
startImportImage: function (index){
719765
index = Number(index)
720766

721-
console.log(`-------startImportImage--'${index}'---------------`)
767+
//console.log(`-------startImportImage--'${index}'---------------`)
722768
if(index+1 < img_elem_keys.length){
723769
//console.log(`---------${img_elem_keys}---------------`)
724-
console.log(`---------'${index}'-----'${img_elem_keys.length}'-----------`)
770+
//console.log(`---------'${index}'-----'${img_elem_keys.length}'-----------`)
725771
switch_tab_dict = {
726772
"img2img_invisible_img2img_image": "switch_to_img2img()",
727773
"img2img_invisible_img2img_sketch": "switch_to_sketch()",
@@ -779,7 +825,11 @@ state.core = (function () {
779825
// });
780826
// break
781827
}
782-
828+
},
829+
preset_output_log: function (preset, key="", value=""){
830+
fetch(`/lightdiffusionflow/local/preset_output_log?preset=${preset}&key=${key}&value=${value}`).then(() => {
831+
gradioApp().getElementById("img2img_invisible_refresh_log").click();
832+
});
783833
},
784834
output_log: function (msg, msg_style=""){
785835
fetch(`/lightdiffusionflow/local/output_log?msg=${msg}&style=${msg_style}`).then(() => {
@@ -789,7 +839,7 @@ state.core = (function () {
789839
output_warning: function (msg, msg_style="color:Orange;"){
790840
actions.output_log(msg,msg_style)
791841
},
792-
output_error: function (msg, msg_style="color:Tomato;"){
842+
output_error: function (msg, msg_style="color:Red;"){
793843
actions.output_log(msg,msg_style)
794844
},
795845
get_sd_version: function (){

javascript/state.utils.js

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ state.utils = {
88
//console.log(state.extensions)
99
// const button = gradioApp().getElementById("lightdiffusionflow_set_elements");
1010
// button.click();
11+
12+
ext_name = "state-ext-control-net-img2img_2-presets".match(/ext-([a-zA-z0-9\-]+)-txt2img/)
13+
console.log(ext_name)
1114
},
1215

1316
target_is_newer_version: function(cur_version, target_version){
@@ -422,8 +425,10 @@ state.utils = {
422425

423426
if(successed){
424427
state.utils.triggerMouseEvent(li, 'mousedown');
425-
state.core.actions.output_warning(
426-
`The option '${value}' was not found, and has been replaced with '${li.lastChild.wholeText.trim()}'!`)
428+
// state.core.actions.output_log(
429+
// `Note: \'<b style="color:Orange;">${value}</b>\' not found. An approximate match \'<b style="color:Orange;">${li.lastChild.wholeText.trim()}</b>\' has been automatically selected as replacement.`
430+
// )
431+
state.core.actions.preset_output_log("alt_option", value, li.lastChild.wholeText.trim())
427432
break
428433
}
429434
}
@@ -434,19 +439,22 @@ state.utils = {
434439
let option_name = store.prefix + id
435440
if(option_name === "state-setting_sd_model_checkpoint"){
436441
// 大模型找不到就只用warning提示,因为不影响运行
437-
state.core.actions.output_warning(`The option \'${value}\' was not found!`)
442+
// state.core.actions.output_log(`Note: \'<b style="color:Orange;">${value}</b>\' not found.`)
443+
state.core.actions.preset_output_log("no_option", "stable diffusion checkpoint", value)
438444
}
439445
else{
440-
state.core.actions.output_error(`\'${option_name}\' import failed! The option \'${value}\' was not found!`)
446+
//state.core.actions.output_log(`Error: \'<b style="color:Red;">${option_name}</b>\' import failed! The option \'<b style="color:Red;">${value}</b>\' was not found!`)
447+
state.core.actions.preset_output_log("no_option", option_name, value)
441448
}
442449
if(hash_res != null){
443450
let model_name = value
444451
let hash_str = hash_res[0]
445452
state.utils.searchCheckPointByHash(hash_str).then( downloadUrl => {
446453
if(downloadUrl != undefined){
447-
let warning_str = encodeURIComponent(`click to download \
448-
<a style ='text-decoration:underline;color:cornflowerblue;', href='${downloadUrl}'> ${model_name} </a>`)
449-
state.core.actions.output_warning(warning_str)
454+
// let warning_str = encodeURIComponent(`Click to download \
455+
// <a style ='text-decoration:underline;color:cornflowerblue;', href='${downloadUrl}'> ${model_name} </a>`)
456+
// state.core.actions.output_warning(warning_str)
457+
state.core.actions.preset_output_log("download_url", model_name, downloadUrl)
450458
}
451459
});
452460
}
@@ -529,8 +537,8 @@ state.utils = {
529537
}
530538
});
531539
if(!successed){
532-
state.core.actions.output_error(`\'${store.prefix + id}\' import failed!`)
533-
state.core.actions.output_error(`The option \'${value}\' was not found!`)
540+
state.core.actions.preset_output_log("no_option", store.prefix + id, value)
541+
//state.core.actions.output_log(`Error: \'<b style="color:Red;">${store.prefix + id}</b>\' import failed! The option \'<b style="color:Red;">${value}</b>\' was not found!`)
534542
}
535543
setTimeout(selectOption, 100);
536544
}, 100);
@@ -567,13 +575,6 @@ state.utils = {
567575
link.href = url;
568576
link.download = fileName;
569577

570-
// // 创建一个<input type="file">元素,并设置其webkitdirectory属性为下载路径
571-
// var fileInput = document.createElement('input');
572-
// fileInput.type = 'file';
573-
// fileInput.style.display = 'none';
574-
// fileInput.webkitdirectory = path;
575-
576-
// document.body.appendChild(fileInput);
577578
document.body.appendChild(link);
578579
link.click();
579580
link.parentNode.removeChild(link);

scripts/lightdiffusionflow_config.py

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,86 @@
11
import json
2-
import modules.shared as shared
32

43
PNGINFO_2_LIGHTDIFFUSIONFLOW = {}
54
PNGINFO_CN_2_LIGHTDIFFUSIONFLOW = {}
65
Image_Components_Key = {}
76

7+
class OutputPrompt_English:
8+
9+
def startimport():
10+
return "<hr style='margin-top:10px;margin-bottom:10px'></hr><b style='color:LimeGreen;'>Start parsing settings...</b>"
11+
12+
def invalid_file():
13+
return "<b style='color:Red;'>Please select a valid lightdiffusionflow or image file!</b>"
14+
15+
def importing_image(image_name):
16+
return f"<b style='color:LimeGreen;'>importing image: '{image_name}'.</b>"
17+
18+
def import_completed():
19+
return "<b style='color:LimeGreen;'>import completed!</b>"
20+
21+
def alternative_option(target_value, new_value):
22+
return f'''Note: '<b style='color:Orange;'>{target_value}</b>' not found.\
23+
An approximate match '<b style='color:Orange;'>{new_value}</b>' has been automatically selected as replacement.'''
24+
25+
def no_option(option_name, value):
26+
return f'''Error: '<b style='color:Red;'>{option_name}</b>' import failed!\
27+
The option '<b style='color:Red;'>{value}</b>' was not found!'''
28+
29+
def missing_extensions(ext_list:[]):
30+
error_str = "Error: <b style='color:Red;'>Found missing extensions.</b></p>"
31+
for ext in ext_list:
32+
error_str+="<p>- <b style='color:Red;'>"+ext+"</b></p> "
33+
return error_str
34+
35+
def click_to_download(file_name, file_url):
36+
return f'''<p style="color:Orange;">Click to download \
37+
<a style ='text-decoration:underline;color:cornflowerblue;', target="_blank", href='{file_url}'> {file_name} </a>
38+
'''
39+
40+
class OutputPrompt_Chinese:
41+
42+
def startimport():
43+
return "<hr style='margin-top:10px;margin-bottom:10px'></hr><b style='color:LimeGreen;'>开始解析设置...</b>"
44+
45+
def invalid_file():
46+
return "<b style='color:Red;'>请选择一个有效的flow文件,或者含png_info数据的图片!</b>"
47+
48+
def importing_image(image_name):
49+
return f"<b style='color:LimeGreen;'>导入图片'{image_name}'...</b>"
50+
51+
def import_completed():
52+
return "<b style='color:LimeGreen;'>导入完成!</b>"
53+
54+
def alternative_option(target_value, new_value):
55+
return f'''注意: 未找到选项'<b style='color:Orange;'>{target_value}</b>'.\
56+
已使用近似选项'<b style='color:Orange;'>{new_value}</b>'代替.'''
57+
58+
def no_option(option_name, value):
59+
if(option_name == "stable diffusion checkpoint"):
60+
return f'''未找到大模型'<b style='color:Orange;'>{value}</b>'!'''
61+
return f'''错误: '<b style='color:Red;'>{option_name}</b>'导入失败!\
62+
未找到选项'<b style='color:Red;'>{value}</b>'!'''
63+
64+
def missing_extensions(ext_list:[]):
65+
error_str = "错误, <b style='color:Red;'>发现缺失的插件:</b></p>"
66+
for ext in ext_list:
67+
error_str+="<p>- <b style='color:Red;'>"+ext+"</b></p> "
68+
return error_str
69+
70+
def click_to_download(file_name, file_url):
71+
name = file_name
72+
if(name == "ControlNet Models"):
73+
name = "常用ControlNet模型"
74+
return f'''<p style="color:Orange;">点击下载 \
75+
<a style ='text-decoration:underline;color:cornflowerblue;', target="_blank", href='https://pan.quark.cn/s/eafa2a9df949'> {name} </a>
76+
'''
77+
78+
OutputPrompt = OutputPrompt_English
79+
880
# 改成函数调用,修改配置之后能及时刷新
981
def init():
10-
global PNGINFO_2_LIGHTDIFFUSIONFLOW,PNGINFO_CN_2_LIGHTDIFFUSIONFLOW,Image_Components_Key
82+
global PNGINFO_2_LIGHTDIFFUSIONFLOW,PNGINFO_CN_2_LIGHTDIFFUSIONFLOW
83+
global OutputPrompt,Image_Components_Key
1184
# PNG Info的功能除了主要的选项以外其他的都靠第三方插件的主动支持,后续再考虑能否有优化的办法
1285
#print(parameters_copypaste.paste_fields)
1386
PNGINFO_2_LIGHTDIFFUSIONFLOW = {
@@ -46,6 +119,32 @@ def init():
46119
"preprocessor params": ""
47120
}
48121

122+
try:
123+
import modules.shared as shared
124+
webui_settings = {}
125+
with open(shared.cmd_opts.ui_settings_file, mode='r') as f:
126+
json_str = f.read()
127+
webui_settings = json.loads(json_str)
128+
try:
129+
if(webui_settings['lightdiffusionflow-language'] == "default"):
130+
localization_files = ["zh_CN", "zh-Hans (Stable) [vladmandic]", "zh-Hans (Stable)",
131+
"zh-Hans (Testing) [vladmandic]", "zh-Hans (Testing)"]
132+
try:
133+
# 如果用户使用了中文汉化文件,插件也默认显示中文
134+
localization_files.index(webui_settings["localization"])
135+
OutputPrompt = OutputPrompt_Chinese
136+
except:
137+
OutputPrompt = OutputPrompt_English
138+
elif(webui_settings['lightdiffusionflow-language'] == "english"):
139+
OutputPrompt = OutputPrompt_English
140+
else:
141+
OutputPrompt = OutputPrompt_Chinese
142+
except KeyError:
143+
pass
144+
except:
145+
# 啥都读不到就默认显示英文
146+
OutputPrompt = OutputPrompt_English
147+
49148
Image_Components_Key = [
50149
# 第一个组件是用来预计算第一张有效图的索引 防止出现有没用的页面跳转
51150
"useless_Textbox",
@@ -79,4 +178,6 @@ def init():
79178
# # Segment Anything images
80179
# Image_Components_Key.extend(["txt2img_sam_input_image","img2img_sam_input_image"])
81180

181+
182+
82183
init()

0 commit comments

Comments
 (0)