Upgrade to v1.0.9

This commit is contained in:
yolain
2024-03-02 17:48:02 +08:00
parent f28cbf78e4
commit f9d01ff53b
7 changed files with 178 additions and 94 deletions
+12 -15
View File
@@ -29,7 +29,7 @@ After installing the node package, the UI interface will be automatically switch
### Stable Cascade
[WorkFlow Example](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#StableCascade) <br><br>
[WorkFlow Example](https://github.com/yolain/ComfyUI-Easy-Use/blob/main/README.en.md#StableCascade) <br><br>
Currently, txt2img and img2img are supported,Lora and Controlnet are comming soon!<br><br>
Usage:<br>
@@ -39,24 +39,21 @@ Usage:<br>
## Changelog
**2024-02-29**
**v1.0.9 [2024-3-2]**
- Fixed `easy svdLoader` error when the positive or negative is empty
- Added `easy instantIDApply` - you need installed [ComfyUI_InstantID](https://github.com/cubiq/ComfyUI_InstantID) fisrt, Workflow[Example](https://github.com/yolain/ComfyUI-Easy-Use/blob/main/README.en.md#InstantID)
- Fixed `easy detailerFix` not added to the list of nodes available for saving images formatting extensions
- Fixed `easy XYInputs: PromptSR` errors are reported when replacing negative prompts
**2024-02-28**
- Fixed the issue that 'easy preSampling' and other similar node, latent could not be generated based on the batch index after passing in
**2024-02-26**
- `easy fullLoader` **positive**、**negative**、**latent** added to the output items
- Fixed the error of SDXLClipModel in ComfyUI revision 2016[c2cb8e88] and above (the revision number was judged to be compatible with the old revision)
- Fixed `easy detailerFix` generation error when batch size is greater than 1
**v1.0.8(2024-02-25)**
**v1.0.8 (f28cbf7)**
- `easy cascadeLoader` stage_c and stage_b support the checkpoint model (Download [checkpoints](https://huggingface.co/stabilityai/stable-cascade/tree/main/comfyui_checkpoints) models)
- `easy styleSelector` The search box is modified to be case-insensitive
- `easy fullLoader` **positive**、**negative**、**latent** added to the output items
- Fixed the issue that 'easy preSampling' and other similar node, latent could not be generated based on the batch index after passing in
- Fixed `easy svdLoader` error when the positive or negative is empty
- Fixed the error of SDXLClipModel in ComfyUI revision 2016[c2cb8e88] and above (the revision number was judged to be compatible with the old revision)
- Fixed `easy detailerFix` generation error when batch size is greater than 1
- Optimize the code, reduce a lot of redundant code and improve the running speed
**v1.0.7 (2024-02-19)**
@@ -66,7 +63,7 @@ Usage:<br>
- Added `easy fullCascadeKSampler` - stable cascade stage-c ksampler full
- Added `easy cascadeKSampler` - stable cascade stage-c ksampler simple
-
- Optimize the image to image[Example](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#image-to-image)
- Optimize the image to image[Example](https://github.com/yolain/ComfyUI-Easy-Use/blob/main/README.en.md#image-to-image)
**v1.0.6**
+16 -20
View File
@@ -43,33 +43,28 @@ stage_c 与 stage_b 可以使用[checkpoints](https://huggingface.co/stabilityai
## 更新日志
**2024-02-29**
- 修复 `easy svdLoader` 报错
**v1.0.9 [2024-3-2]**
**2024-02-28**
- 新增 `easy instantIDApply` - 需要先安装 [ComfyUI_InstantID](https://github.com/cubiq/ComfyUI_InstantID), 工作流参考[示例](https://github.com/yolain/ComfyUI-Easy-Use?tab=readme-ov-file#InstantID)
- 修复 `easy detailerFix` 未添加到保存图片格式化扩展名可用节点列表
- 修复 `easy XYInputs: PromptSR` 在替换负面提示词时报错
**v1.0.8 (f28cbf7)**
- `easy cascadeLoader` stage_c 与 stage_b 支持checkpoint模型 (需要下载[checkpoints](https://huggingface.co/stabilityai/stable-cascade/tree/main/comfyui_checkpoints))
- `easy styleSelector` 搜索框修改为不区分大小写匹配
- `easy fullLoader` 增加 **positive**、**negative**、**latent** 输出项
- 修复 SDXLClipModel 在 ComfyUI 修订版本号 2016[c2cb8e88] 及以上的报错(判断了版本号可兼容老版本)
- 修复 `easy detailerFix` 批次大小大于1时生成出错
- 修复`easy preSampling`等 latent传入后无法根据批次索引生成的问题
**2024-02-27**
- 修复 `easy svdLoader` 报错
- 优化代码,减少了诸多冗余,提升运行速度
- 去除中文翻译对照文本
(翻译对照已由 [AIGODLIKE-COMFYUI-TRANSLATION](https://github.com/AIGODLIKE/AIGODLIKE-ComfyUI-Translation) 统一维护啦!
首次下载或者版本较早的朋友请更新 AIGODLIKE-COMFYUI-TRANSLATION 和本节点包至最新版本。)
**2024-02-26**
- `easy fullLoader` 增加 **positive**、**negative**、**latent** 输出项
- 修复 SDXLClipModel 在 ComfyUI 修订版本号 2016[c2cb8e88] 及以上的报错(判断了版本号可兼容老版本)
- 修复 `easy detailerFix` 批次大小大于1时生成出错
**v1.0.8(2024-02-25)**
- `easy cascadeLoader` stage_c 与 stage_b 支持checkpoint模型 (需要下载[checkpoints](https://huggingface.co/stabilityai/stable-cascade/tree/main/comfyui_checkpoints))
- `easy styleSelector` 搜索框修改为不区分大小写匹配
- 优化代码,减少了诸多冗余,提升运行速度
**v1.0.7**
- 增加 `easy cascadeLoader` - stable cascade 加载器
@@ -255,9 +250,9 @@ stage_c 与 stage_b 可以使用[checkpoints](https://huggingface.co/stabilityai
<img src="https://raw.githubusercontent.com/yolain/yolain-comfyui-workflow/main/Workflows/Simple/image_to_image_controlnet.png">
#### SDTurbo+高清修复+SVD
#### InstantID
<img src="https://raw.githubusercontent.com/yolain/yolain-comfyui-workflow/main/Workflows/Simple/sdturbo_hiresfix_svd.png">
<img src="https://raw.githubusercontent.com/yolain/yolain-comfyui-workflow/main/Workflows/Simple/instantID.png">
### StableCascade
#### 文生图
@@ -266,6 +261,7 @@ stage_c 与 stage_b 可以使用[checkpoints](https://huggingface.co/stabilityai
#### 图生图
<img src="https://raw.githubusercontent.com/yolain/yolain-comfyui-workflow/main/Workflows/StableCascade/image_to_image.png">
## Credits
[ComfyUI](https://github.com/comfyanonymous/ComfyUI) - 功能强大且模块化的Stable Diffusion GUI
+1 -1
View File
@@ -74,4 +74,4 @@ WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', "WEB_DIRECTORY"]
print('\033[34mComfy-Easy-Use (v1.0.8): \033[92mLoaded\033[0m')
print('\033[34mComfy-Easy-Use (v1.0.9): \033[92mLoaded\033[0m')
+91 -22
View File
@@ -1441,6 +1441,7 @@ class controlnetSimple:
"loader_settings": pipe["loader_settings"]
}
del pipe
return (new_pipe, positive, negative)
# controlnetADV
@@ -1535,6 +1536,8 @@ class LLLiteLoader:
return (model_lllite,)
#---------------------------------------------------------------测试 开始----------------------------------------------------------------------#
# FooocusInpaint (Testing)
from .fooocus import InpaintHead, InpaintWorker
inpaint_head_model = None
@@ -1567,6 +1570,90 @@ class fooocusInpaintLoader:
return ((inpaint_head_model, inpaint_lora),)
#Apply InstantID
class instantIDApply:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required":{
"pipe": ("PIPE_LINE",),
"image": ("IMAGE",),
"instantid_file": (folder_paths.get_filename_list("instantid"),),
"insightface": (["CPU", "CUDA", "ROCM"],),
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
"cn_strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"cn_soft_weights": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001},),
"weight": ("FLOAT", {"default": .8, "min": 0.0, "max": 5.0, "step": 0.01, }),
"start_at": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001, }),
"end_at": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001, }),
"noise": ("FLOAT", {"default": 0.35, "min": 0.0, "max": 1.0, "step": 0.05, }),
},
"optional": {
"image_kps": ("IMAGE",),
"mask": ("MASK",),
"control_net": ("CONTROL_NET",),
},
"hidden": {
"prompt": "PROMPT", "extra_pnginfo": "EXTRA_PNGINFO", "my_unique_id": "UNIQUE_ID"
},
}
RETURN_TYPES = ("PIPE_LINE", "MODEL", "CONDITIONING", "CONDITIONING")
RETURN_NAMES = ("pipe", "model", "positive", "negative")
OUTPUT_NODE = True
FUNCTION = "apply"
CATEGORY = "EasyUse/__for_testing"
def error(self):
raise Exception(f"[ERROR] To use instantIDApply, you need to install 'ComfyUI_InstantID'")
def apply(self, pipe, image, instantid_file, insightface, control_net_name, cn_strength, cn_soft_weights, weight, start_at, end_at, noise, image_kps=None, mask=None, control_net=None, prompt=None, extra_pnginfo=None, my_unique_id=None):
instantid_model, insightface_model, face_embeds = None, None, None
model = pipe['model']
positive = pipe['positive']
negative = pipe['negative']
# Load InstantID
if "InstantIDModelLoader" in ALL_NODE_CLASS_MAPPINGS:
load_instant_cls = ALL_NODE_CLASS_MAPPINGS["InstantIDModelLoader"]
instantid_model, = load_instant_cls().load_model(instantid_file)
else:
self.error()
if "InstantIDFaceAnalysis" in ALL_NODE_CLASS_MAPPINGS:
load_insightface_cls = ALL_NODE_CLASS_MAPPINGS["InstantIDFaceAnalysis"]
insightface_model, = load_insightface_cls().load_insight_face(insightface)
else:
self.error()
# Apply InstantID
if "ApplyInstantID" in ALL_NODE_CLASS_MAPPINGS:
instantid_apply = ALL_NODE_CLASS_MAPPINGS['ApplyInstantID']
control_net = easyControlnet().load_controlnet(control_net_name, control_net, cn_soft_weights)
model, positive, negative = instantid_apply().apply_instantid(instantid_model, insightface_model, control_net, image, model, positive, negative, start_at, end_at, weight=weight, ip_weight=None, cn_strength=cn_strength, noise=noise, image_kps=image_kps, mask=None)
else:
self.error()
new_pipe = {
"model": model,
"positive": positive,
"negative": negative,
"vae": pipe['vae'],
"clip": pipe['clip'],
"samples": pipe["samples"],
"images": pipe["images"],
"seed": 0,
"loader_settings": pipe["loader_settings"]
}
del pipe
return (new_pipe, model, positive, negative)
#---------------------------------------------------------------预采样 开始----------------------------------------------------------------------#
# 预采样设置(基础)
@@ -3373,26 +3460,6 @@ class detailerFix:
return {"ui": {"images": results}, "result": (new_pipe, result_img, result_cropped_enhanced, result_cropped_enhanced_alpha, result_mask, result_cnet_images )}
def add_folder_path_and_extensions(folder_name, full_folder_paths, extensions):
for full_folder_path in full_folder_paths:
folder_paths.add_model_folder_path(folder_name, full_folder_path)
if folder_name in folder_paths.folder_names_and_paths:
current_paths, current_extensions = folder_paths.folder_names_and_paths[folder_name]
updated_extensions = current_extensions | extensions
folder_paths.folder_names_and_paths[folder_name] = (current_paths, updated_extensions)
else:
folder_paths.folder_names_and_paths[folder_name] = (full_folder_paths, extensions)
model_path = folder_paths.models_dir
add_folder_path_and_extensions("ultralytics_bbox", [os.path.join(model_path, "ultralytics", "bbox")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("ultralytics_segm", [os.path.join(model_path, "ultralytics", "segm")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("ultralytics", [os.path.join(model_path, "ultralytics")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("mmdets_bbox", [os.path.join(model_path, "mmdets", "bbox")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("mmdets_segm", [os.path.join(model_path, "mmdets", "segm")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("mmdets", [os.path.join(model_path, "mmdets")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("sams", [os.path.join(model_path, "sams")], folder_paths.supported_pt_extensions)
add_folder_path_and_extensions("onnx", [os.path.join(model_path, "onnx")], {'.onnx'})
class ultralyticsDetectorForDetailerFix:
@classmethod
def INPUT_TYPES(s):
@@ -4697,7 +4764,8 @@ NODE_CLASS_MAPPINGS = {
# "easy imageRemoveBG": imageREMBG,
"dynamicThresholdingFull": dynamicThresholdingFull,
# __for_testing 测试
"easy fooocusInpaintLoader": fooocusInpaintLoader
"easy fooocusInpaintLoader": fooocusInpaintLoader,
"easy instantIDApply": instantIDApply,
}
NODE_DISPLAY_NAME_MAPPINGS = {
# prompt 提示词
@@ -4773,5 +4841,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"easy imageRemoveBG": "ImageRemoveBG",
"dynamicThresholdingFull": "DynamicThresholdingFull",
# __for_testing 测试
"easy fooocusInpaintLoader": "Load Fooocus Inpaint"
"easy fooocusInpaintLoader": "Load Fooocus Inpaint",
"easy instantIDApply": "Easy Apply InstantID"
}
+56 -34
View File
@@ -1,12 +1,13 @@
import folder_paths
import comfy.controlnet
import comfy.model_management
from nodes import NODE_CLASS_MAPPINGS
class easyControlnet:
def __init__(self):
pass
def apply(self, control_net_name, image, positive, negative, strength, start_percent=0, end_percent=1, control_net=None, scale_soft_weights=1):
def load_controlnet(self, control_net_name, control_net, scale_soft_weights):
if control_net is None:
if scale_soft_weights < 1:
if "ScaledSoftControlNetWeights" in NODE_CLASS_MAPPINGS:
@@ -19,43 +20,64 @@ class easyControlnet:
else:
controlnet_path = folder_paths.get_full_path("controlnet", control_net_name)
control_net = comfy.controlnet.load_controlnet(controlnet_path)
return control_net
def apply(self, control_net_name, image, positive, negative, strength, start_percent=0, end_percent=1, control_net=None, scale_soft_weights=1, mask=None):
if strength == 0:
return (positive, negative)
control_net = self.load_controlnet(control_net_name, control_net, scale_soft_weights)
if mask is not None:
mask = mask.to(self.device)
if mask is not None and len(mask.shape) < 3:
mask = mask.unsqueeze(0)
control_hint = image.movedim(-1, 1)
if strength != 0:
if negative is None:
p = []
for t in positive:
n = [t[0], t[1].copy()]
c_net = control_net.copy().set_cond_hint(control_hint, strength, (start_percent, end_percent))
if 'control' in t[1]:
c_net.set_previous_controlnet(t[1]['control'])
n[1]['control'] = c_net
n[1]['control_apply_to_uncond'] = True
p.append(n)
positive = p
else:
cnets = {}
out = []
for conditioning in [positive, negative]:
c = []
for t in conditioning:
d = t[1].copy()
is_cond = True
if negative is None:
p = []
for t in positive:
n = [t[0], t[1].copy()]
c_net = control_net.copy().set_cond_hint(control_hint, strength, (start_percent, end_percent))
if 'control' in t[1]:
c_net.set_previous_controlnet(t[1]['control'])
n[1]['control'] = c_net
n[1]['control_apply_to_uncond'] = True
if mask is not None:
n[1]['mask'] = mask
n[1]['set_area_to_bounds'] = False
p.append(n)
positive = p
else:
cnets = {}
out = []
for conditioning in [positive, negative]:
c = []
for t in conditioning:
d = t[1].copy()
prev_cnet = d.get('control', None)
if prev_cnet in cnets:
c_net = cnets[prev_cnet]
else:
c_net = control_net.copy().set_cond_hint(control_hint, strength, (start_percent, end_percent))
c_net.set_previous_controlnet(prev_cnet)
cnets[prev_cnet] = c_net
prev_cnet = d.get('control', None)
if prev_cnet in cnets:
c_net = cnets[prev_cnet]
else:
c_net = control_net.copy().set_cond_hint(control_hint, strength, (start_percent, end_percent))
c_net.set_previous_controlnet(prev_cnet)
cnets[prev_cnet] = c_net
d['control'] = c_net
d['control_apply_to_uncond'] = False
n = [t[0], d]
c.append(n)
out.append(c)
positive = out[0]
negative = out[1]
d['control'] = c_net
d['control_apply_to_uncond'] = False
if mask is not None:
d['mask'] = mask
d['set_area_to_bounds'] = False
n = [t[0], d]
c.append(n)
out.append(c)
positive = out[0]
negative = out[1]
return (positive, negative)
+1 -1
View File
@@ -367,7 +367,7 @@ class easyXYPlot():
w_max=1.0,
apply_to_pooled="enable", a1111_prompt_style=a1111_prompt_style, steps=steps)
if "negative_cond" in plot_image_vars:
positive = positive + plot_image_vars["negative_cond"]
negative = negative + plot_image_vars["negative_cond"]
# ControlNet
if "ControlNet" in self.x_type or "ControlNet" in self.y_type:
+1 -1
View File
@@ -4,7 +4,7 @@ import { applyTextReplacements } from "/scripts/utils.js";
app.registerExtension({
name: "Comfy.Easy.SaveImageExtraOutput",
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (["easy imageSave", "easy fullkSampler", "easy kSampler", "easy kSamplerTiled","easy kSamplerInpainting", "easy kSamplerDownscaleUnet", "easy kSamplerSDTurbo"].includes(nodeData.name)) {
if (["easy imageSave", "easy fullkSampler", "easy kSampler", "easy kSamplerTiled","easy kSamplerInpainting", "easy kSamplerDownscaleUnet", "easy kSamplerSDTurbo","easy detailerFix"].includes(nodeData.name)) {
const onNodeCreated = nodeType.prototype.onNodeCreated;
// When the SaveImage node is created we want to override the serialization of the output name widget to run our S&R
nodeType.prototype.onNodeCreated = function () {