add:easy promptList

This commit is contained in:
yolain
2024-01-29 19:46:57 +08:00
parent cc98f6d788
commit 84daa7d72e
9 changed files with 266 additions and 49 deletions
+27 -3
View File
@@ -42,6 +42,15 @@
"text": "提示词"
}
},
"easy promptList": {
"title": "提示词列表",
"inputs": {
"optional_prompt_list": "列表(可选)"
},
"outputs": {
"prompt_list": "列表"
}
},
"easy stylesSelector": {
"title": "风格提示词选择器",
"inputs": {
@@ -330,10 +339,12 @@
"pipe": "节点束",
"source_latent": "潜空间(源)",
"source_mask": "遮罩(源)",
"new_mask": "遮罩(新)"
"destination_mask": "遮罩(目标)"
},
"widgets": {
"text_combine": "文字拼接"
"text_combine": "文字拼接",
"text_combine_mode": "文字拼接模式",
"replace_text": "替换文字"
},
"outputs": {
"pipe": "节点束",
@@ -756,6 +767,18 @@
"positive_4": "反向条件_4"
}
},
"easy XYInputs: PositiveCondList": {
"title": "XY输入: 正向条件列表",
"inputs": {
"positive": "正向条件列表"
}
},
"easy XYInputs: NegativeCondList": {
"title": "XY输入: 反向条件列表",
"inputs": {
"negative": "反向条件列表"
}
},
"easy XYInputs: PromptSR": {
"title": "XY输入: 替换提示词",
"widgets": {
@@ -1178,7 +1201,8 @@
"images": "图像"
},
"widgets": {
"filename_prefix": "图片名前缀"
"filename_prefix": "图片名前缀",
"only_preview": "仅预览"
}
},
"easy joinImageBatch": {
+26 -7
View File
@@ -29,6 +29,13 @@ After installing the node package, the UI interface will be automatically switch
## Changelog
**2024-01-29**
- Changing the first-time install node package no longer automatically replaces the theme, you need to manually adjust and refresh the page
- `easy imageSave` added **only_preivew**
- Added `easy promptList`
- Adjust the `easy latentCompositeMaskedWithCond` node
**v1.0.4(2024-01-28)**
- `easy kSamplerInpainting` Added the **patch** input value to be used with the FooocusInpaintLoader node
@@ -39,19 +46,23 @@ After installing the node package, the UI interface will be automatically switch
- Fixed `easy XYInputs: ControlNet` Error
- Fixed `easy loraStack` error when **toggle** is disabled
**2024-01-22**
<details>
<summary><b>2024-01-22</b></summary>
- Fixed `easy XYInputs: Sampler/Scheduler` Error
- Fixed the right menu has a problem when clicking the button
- Adjust the UI theme, divided into two sets of styles: the official default background and the dark black background, which can be switched in the color palette in the settings
</details>
**2024-01-21**
<details>
<summary><b>22024-01-21</b></summary>
- Modify the styles path to be compatible with other environments
- Fixed `easy comfyLoader` error
- Fixed xyPlot error when connecting to zero123
</details>
**v1.0.3(2024-01-19)**
v1.0.3(2024-01-19)**
- Fixed the error message in the loader when the prompt word was component
- Added `easy stylesSelector`
@@ -60,25 +71,33 @@ After installing the node package, the UI interface will be automatically switch
- Fixed `easy getNode` and `easy setNode` the title does not change when loading
- Fixed all samplers using subdirectories to store images
**2024-01-12**
<details>
<summary><b>2024-01-12</b></summary>
- Fixed UI loading failure in the new version of ComfyUI
</details>
**2024-01-11**
<details>
<summary><b>2024-01-11</b></summary>
- Replaced the font file used in the generation of XY diagrams
</details>
**2024-01-09**
<details>
<summary><b>2024-01-09</b></summary>
- Fixed XYPlot is not working when `a1111_prompt_style` is True
- An `autocomplete` folder has been added, If you have [ComfyUI-Custom-Scripts](https://github.com/pythongosssss/ComfyUI-Custom-Scripts) installed, the txt files in that folder will be merged and overwritten to the autocomplete .txt file of the pyssss package at startup.
- Added a `📜Groups Map(EasyUse)` to the context menu.
</details>
**2024-01-08**
<details>
<summary><b>2024-01-08</b></summary>
- `easy XYInputs ModelMergeBlocks` Values can be imported from CSV files
- Fixed `easy pipeToBasicPipe` Bug
- Removed `easy imageRemBg`
</details>
**v1.0.2(2024-01-05)**
+8 -1
View File
@@ -28,7 +28,7 @@
### UI界面美化
安装节点包后会自动切换UI界面,如需更换其他主题请在 Settings -> Color Palette 中自行切换并刷新页面即可。
首次安装的用户,如需使用本节点包UI主题,请在安装节点包在 Settings -> Color Palette 中自行切换并**刷新页面**即可。
### 简体中文节点
@@ -37,6 +37,13 @@
## 更新日志
**2024-01-29**
- 更改首次安装节点包不再自动替换主题,需手动调整并刷新页面
- `easy imageSave` 增加 **only_preivew**
- 增加 `easy promptList` - 提示词列表
- 修改 `easy latentCompositeMaskedWithCond`
**v1.0.4(2024-01-28)**
- `easy kSamplerInpainting` 增加 **patch** 传入值,配合Fooocus内补节点使用
+1 -1
View File
@@ -87,4 +87,4 @@ WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', "WEB_DIRECTORY"]
print('\033[34mComfy-Easy-Use (v1.0.3): \033[92mLoaded\033[0m')
print('\033[34mComfy-Easy-Use (v1.0.4): \033[92mLoaded\033[0m')
+140 -31
View File
@@ -1394,6 +1394,44 @@ class stylesPromptSelector:
return (positive_prompt, negative_prompt)
#promptList
class promptList:
@classmethod
def INPUT_TYPES(cls):
return {"required": {
"prompt_1": ("STRING", {"multiline": True, "default": ""}),
"prompt_2": ("STRING", {"multiline": True, "default": ""}),
"prompt_3": ("STRING", {"multiline": True, "default": ""}),
"prompt_4": ("STRING", {"multiline": True, "default": ""}),
"prompt_5": ("STRING", {"multiline": True, "default": ""}),
},
"optional": {
"optional_prompt_list": ("LIST",)
}
}
RETURN_TYPES = ("LIST",)
RETURN_NAMES = ("prompt_list",)
FUNCTION = "run"
CATEGORY = "EasyUse/Prompt"
def run(self, **kwargs):
prompts = []
if "optional_prompt_list" in kwargs:
for l in kwargs["optional_prompt_list"]:
prompts.append(l)
# Iterate over the received inputs in sorted order.
for k in sorted(kwargs.keys()):
v = kwargs[k]
# Only process string input ports.
if isinstance(v, str) and v != '':
prompts.append(v)
return (prompts,)
# 肖像大师
# Created by AI Wiz Art (Stefano Flore)
# Version: 2.2
@@ -1669,14 +1707,17 @@ class latentCompositeMaskedWithCond:
return {
"required": {
"pipe": ("PIPE_LINE",),
"text_combine": ("STRING", {"default": ""}),
"text_combine": ("LIST",),
"source_latent": ("LATENT",),
"source_mask": ("MASK",),
"new_mask": ("MASK",),
"destination_mask": ("MASK",),
"text_combine_mode": (["add", "replace", "cover"], {"default": "add"}),
"replace_text": ("STRING", {"default": ""})
},
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"},
}
OUTPUT_IS_LIST = (False, False, True)
RETURN_TYPES = ("PIPE_LINE", "LATENT", "CONDITIONING")
RETURN_NAMES = ("pipe", "latent", "conditioning",)
FUNCTION = "run"
@@ -1684,43 +1725,53 @@ class latentCompositeMaskedWithCond:
CATEGORY = "EasyUse/Latent"
def run(self, pipe, text_combine, source_latent, source_mask, new_mask, prompt=None, extra_pnginfo=None, my_unique_id=None):
def run(self, pipe, text_combine, source_latent, source_mask, destination_mask, text_combine_mode, replace_text, prompt=None, extra_pnginfo=None, my_unique_id=None):
clip = pipe["clip"]
destination_latent = pipe["samples"]
positive = pipe["loader_settings"]["positive"] + ',' + text_combine
positive_token_normalization = pipe["loader_settings"]["positive_token_normalization"]
positive_weight_interpretation = pipe["loader_settings"]["positive_weight_interpretation"]
a1111_prompt_style = pipe["loader_settings"]["a1111_prompt_style"]
positive_cond = pipe["positive"]
log_node_warn("正在处理提示词编码...")
# Use new clip text encode by smzNodes like same as webui, when if you installed the smzNodes
if a1111_prompt_style:
if "smZ CLIPTextEncode" in ALL_NODE_CLASS_MAPPINGS:
cls = ALL_NODE_CLASS_MAPPINGS['smZ CLIPTextEncode']
steps = pipe["loader_settings"]["steps"] if "steps" in pipe["loader_settings"] else 5
positive_embeddings_final, = cls().encode(clip, positive, "A1111", True, True, False, False, 6, 1024,
1024, 0, 0, 1024, 1024, '', '', steps)
conds = []
for text in text_combine:
if text_combine_mode == 'cover':
positive = text
elif text_combine_mode == 'replace' and replace_text != '':
positive = pipe["loader_settings"]["positive"].replace(replace_text, text)
else:
raise Exception(f"[ERROR] To use clip text encode same as webui, you need to install 'smzNodes'")
else:
positive_embeddings_final, positive_pooled = advanced_encode(clip, positive,
positive_token_normalization,
positive_weight_interpretation, w_max=1.0,
apply_to_pooled='enable')
positive_embeddings_final = [[positive_embeddings_final, {"pooled_output": positive_pooled}]]
positive = pipe["loader_settings"]["positive"] + ',' + text
positive_token_normalization = pipe["loader_settings"]["positive_token_normalization"]
positive_weight_interpretation = pipe["loader_settings"]["positive_weight_interpretation"]
a1111_prompt_style = pipe["loader_settings"]["a1111_prompt_style"]
positive_cond = pipe["positive"]
# source cond
(cond_1,) = ConditioningSetMask().append(positive_cond, source_mask, "default", 1)
(cond_2,) = ConditioningSetMask().append(positive_embeddings_final, new_mask, "default", 1)
positive_cond = cond_1 + cond_2
log_node_warn("正在处理提示词编码...")
# Use new clip text encode by smzNodes like same as webui, when if you installed the smzNodes
if a1111_prompt_style:
if "smZ CLIPTextEncode" in ALL_NODE_CLASS_MAPPINGS:
cls = ALL_NODE_CLASS_MAPPINGS['smZ CLIPTextEncode']
steps = pipe["loader_settings"]["steps"] if "steps" in pipe["loader_settings"] else 5
positive_embeddings_final, = cls().encode(clip, positive, "A1111", True, True, False, False, 6, 1024,
1024, 0, 0, 1024, 1024, '', '', steps)
else:
raise Exception(f"[ERROR] To use clip text encode same as webui, you need to install 'smzNodes'")
else:
positive_embeddings_final, positive_pooled = advanced_encode(clip, positive,
positive_token_normalization,
positive_weight_interpretation, w_max=1.0,
apply_to_pooled='enable')
positive_embeddings_final = [[positive_embeddings_final, {"pooled_output": positive_pooled}]]
# source cond
(cond_1,) = ConditioningSetMask().append(positive_cond, source_mask, "default", 1)
(cond_2,) = ConditioningSetMask().append(positive_embeddings_final, destination_mask, "default", 1)
positive_cond = cond_1 + cond_2
conds.append(positive_cond)
# latent composite masked
(samples,) = LatentCompositeMasked().composite(destination_latent, source_latent, 0, 0, False)
new_pipe = {
**pipe,
"positive": positive_cond,
"samples": samples,
"loader_settings": {
**pipe["loader_settings"],
@@ -1730,7 +1781,7 @@ class latentCompositeMaskedWithCond:
del pipe
return (new_pipe, samples, positive_cond)
return (new_pipe, samples, conds)
# 随机种
class easySeed:
@@ -4979,6 +5030,58 @@ class XYplot_Negative_Cond:
return ({"axis": axis, "values": values, "cond": cond},) if values is not None else (None,)
# XYPlot Pos Condition List
class XYplot_Positive_Cond_List:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"positive": ("CONDITIONING",),
}
}
INPUT_IS_LIST = True
RETURN_TYPES = ("X_Y",)
RETURN_NAMES = ("X or Y",)
FUNCTION = "xy_value"
CATEGORY = "EasyUse/XY Inputs"
def xy_value(self, positive):
axis = "advanced: Pos Condition"
values = []
cond = []
for index, c in enumerate(positive):
values.append(str(index))
cond.append(c)
return ({"axis": axis, "values": values, "cond": cond},) if values is not None else (None,)
# XYPlot Neg Condition List
class XYplot_Negative_Cond_List:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"negative": ("CONDITIONING",),
}
}
INPUT_IS_LIST = True
RETURN_TYPES = ("X_Y",)
RETURN_NAMES = ("X or Y",)
FUNCTION = "xy_value"
CATEGORY = "EasyUse/XY Inputs"
def xy_value(self, negative):
axis = "advanced: Neg Condition"
values = []
cond = []
for index, c in enumerate(negative):
values.append(index)
cond.append(c)
return ({"axis": axis, "values": values, "cond": cond},) if values is not None else (None,)
# XY Plot: ControlNet
class XYplot_Control_Net:
parameters = ["strength", "start_percent", "end_percent"]
@@ -5137,6 +5240,7 @@ NODE_CLASS_MAPPINGS = {
"easy positive": positivePrompt,
"easy negative": negativePrompt,
"easy wildcards": wildcardsPrompt,
"easy promptList": promptList,
"easy stylesSelector": stylesPromptSelector,
"easy portraitMaster": portraitMaster,
# loaders 加载器
@@ -5189,7 +5293,9 @@ NODE_CLASS_MAPPINGS = {
"easy XYInputs: PromptSR": XYplot_PromptSR,
"easy XYInputs: ControlNet": XYplot_Control_Net,
"easy XYInputs: PositiveCond": XYplot_Positive_Cond,
"easy XYInputs: PositiveCondList": XYplot_Positive_Cond_List,
"easy XYInputs: NegativeCond": XYplot_Negative_Cond,
"easy XYInputs: NegativeCondList": XYplot_Negative_Cond_List,
# others 其他
"easy showSpentTime": showSpentTime,
# "easy imageRemoveBG": imageREMBG,
@@ -5202,6 +5308,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"easy positive": "Positive",
"easy negative": "Negative",
"easy wildcards": "Wildcards",
"easy promptList": "PromptList",
"easy stylesSelector": "Styles Selector",
"easy portraitMaster": "Portrait Master",
# loaders 加载器
@@ -5254,8 +5361,10 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"easy XYInputs: ModelMergeBlocks": "XY Inputs: ModelMergeBlocks //EasyUse",
"easy XYInputs: PromptSR": "XY Inputs: PromptSR //EasyUse",
"easy XYInputs: ControlNet": "XY Inputs: Controlnet //EasyUse",
"easy XYInputs: PositiveCond": "XY Inputs: PositiveCond //EasyUse",
"easy XYInputs: NegativeCond": "XY Inputs: NegativeCond //EasyUse",
"easy XYInputs: PositiveCond": "XY Inputs: PosCond //EasyUse",
"easy XYInputs: PositiveCondList": "XY Inputs: PosCondList //EasyUse",
"easy XYInputs: NegativeCond": "XY Inputs: NegCond //EasyUse",
"easy XYInputs: NegativeCondList": "XY Inputs: NegCondList //EasyUse",
# others 其他
"easy showSpentTime": "ShowSpentTime",
"easy imageRemoveBG": "ImageRemoveBG",
+23 -4
View File
@@ -2,6 +2,7 @@ from PIL import Image
from PIL.PngImagePlugin import PngInfo
from enum import Enum
import datetime
import random
import re
import json
import os
@@ -410,12 +411,17 @@ class imageSaveSimple:
def __init__(self):
self.output_dir = folder_paths.get_output_directory()
self.type = "output"
self.prefix_append = ""
self.compress_level = 4
@classmethod
def INPUT_TYPES(s):
return {"required":
{"images": ("IMAGE",),
"filename_prefix": ("STRING", {"default": "ComfyUI"}),},
{
"images": ("IMAGE",),
"filename_prefix": ("STRING", {"default": "ComfyUI"}),
"only_preview": ("BOOLEAN", {"default": False}),
},
"hidden": {"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO"},
}
@@ -450,10 +456,23 @@ class imageSaveSimple:
text = text.replace(format_str, str(date_formats[format_str](date)))
return text
def save(self, images, filename_prefix="ComfyUI", prompt=None, extra_pnginfo=None):
def save(self, images, filename_prefix="ComfyUI", only_preview=False, prompt=None, extra_pnginfo=None):
if only_preview:
self.output_dir = folder_paths.get_temp_directory()
self.prefix_append = "_temp_" + ''.join(random.choice("abcdefghijklmnopqrstupvxyz") for x in range(5))
self.type = 'temp'
self.compress_level = 1
else:
self.output_dir = folder_paths.get_output_directory()
self.type = "output"
self.prefix_append = ""
self.compress_level = 4
filename_prefix = re.sub(r'%date:(.*?)%', lambda m: self._format_date(m.group(1), datetime.datetime.now()),
filename_prefix)
filename_prefix += self.prefix_append
full_output_folder, filename, counter, subfolder, filename_prefix = folder_paths.get_save_image_path(filename_prefix, self.output_dir, images[0].shape[1], images[0].shape[0])
results = list()
@@ -470,7 +489,7 @@ class imageSaveSimple:
metadata.add_text(x, json.dumps(extra_pnginfo[x]))
file = f"{filename}_{counter:05}_.png"
img.save(os.path.join(full_output_folder, file), pnginfo=metadata)
img.save(os.path.join(full_output_folder, file), pnginfo=metadata, compress_level=self.compress_level)
results.append({
"filename": file,
"subfolder": subfolder,
+29
View File
@@ -248,6 +248,33 @@ class Boolean:
def execute(self, value):
return (value,)
# ---------------------------------------------------------------开关 开始----------------------------------------------------------------------#
class imageSwitch:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image_a": ("IMAGE",),
"image_b": ("IMAGE",),
"boolean": ("BOOLEAN", {"default": False}),
}
}
RETURN_TYPES = ("IMAGE",)
FUNCTION = "image_switch"
CATEGORY = "EasyUse/Logic/Switch"
def image_switch(self, image_a, image_b, boolean):
if boolean:
return (image_a, )
else:
return (image_b, )
# ---------------------------------------------------------------运算 开始----------------------------------------------------------------------#
COMPARE_FUNCTIONS = {
@@ -404,6 +431,7 @@ NODE_CLASS_MAPPINGS = {
"easy rangeFloat": RangeFloat,
"easy boolean": Boolean,
"easy compare": Compare,
"easy imageSwitch": imageSwitch,
"easy if": If,
"easy xyAny": xyAny,
"easy convertAnything": ConvertAnything,
@@ -417,6 +445,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"easy rangeFloat": "Range(Float)",
"easy boolean": "Boolean",
"easy compare": "Compare",
"easy imageSwitch": "Image Switch",
"easy if": "If",
"easy xyAny": "XYAny",
"easy convertAnything": "ConvertAnything",
+10 -1
View File
@@ -167,6 +167,14 @@ function widgetLogic(node, widget) {
widget.options = {on: 'Enabled', off: 'Disabled'}
}
if(widget.name == 'text_combine_mode'){
if(widget.value == 'replace'){
toggleWidget(node, findWidgetByName(node, 'replace_text'), true)
}else{
toggleWidget(node, findWidgetByName(node, 'replace_text'))
}
updateNodeHeight(node)
}
}
function widgetLogic2(node, widget) {
@@ -344,6 +352,7 @@ app.registerExtension({
case "easy XYInputs: ControlNet":
case "easy rangeInt":
case "easy rangeFloat":
case 'easy latentCompositeMaskedWithCond':
getSetters(node)
break
case "easy wildcards":
@@ -731,7 +740,7 @@ const getSetWidgets = ['rescale_after_model', 'rescale', 'image_output',
'refiner_lora1_name', 'refiner_lora2_name', 'upscale_method',
'image_output', 'add_noise', 'info', 'sampler_name',
'ckpt_B_name', 'ckpt_C_name', 'save_model', 'refiner_ckpt_name',
'num_loras', 'mode', 'toggle', 'resolution', 'target_parameter', 'input_count', 'replace_count', 'downscale_mode', 'range_mode']
'num_loras', 'mode', 'toggle', 'resolution', 'target_parameter', 'input_count', 'replace_count', 'downscale_mode', 'range_mode','text_combine_mode']
function getSetters(node) {
if (node.widgets)
+2 -1
View File
@@ -106,7 +106,7 @@ try{
ui2.colors.litegraph_base.CLEAR_BACKGROUND_COLOR = '#000'
custom_theme[ui2.id] = ui2
localStorage.setItem('Comfy.Settings.Comfy.CustomColorPalettes', JSON.stringify(custom_theme));
localStorage.setItem('Comfy.Settings.Comfy.ColorPalette',`"${custom_theme_name}"`)
// localStorage.setItem('Comfy.Settings.Comfy.ColorPalette',`"${custom_theme_name}"`)
}
const theme_name = localStorage.getItem('Comfy.Settings.Comfy.ColorPalette')
// 兼容 ComfyUI Revision: 1887 [235727fe] 以上版本
@@ -834,6 +834,7 @@ const COLOR_THEMES = LGraphCanvas.node_colors
const NODE_COLORS = {
"easy positive":"green",
"easy negative":"red",
"easy promptList":"cyan",
"easy XYInputs: Seeds++ Batch": customXYLink,
"easy XYInputs: ModelMergeBlocks": customXYLink,
}