Add easy controlnetPlusPlus
This commit is contained in:
@@ -45,6 +45,7 @@ Double-click install.bat to install the required dependencies
|
||||
|
||||
**v1.2.1**
|
||||
|
||||
- Added `easy controlnetLoader++`
|
||||
- Added **PLUS (kolors genernal)** preset to `easy ipadapterApply` and `easy ipadapterApplyADV` (Supported kolors ipadapter)
|
||||
- Added `easy kolorsLoader` - Code based on [MinusZoneAI](https://github.com/MinusZoneAI/ComfyUI-Kolors-MZ)'s and [kijai](https://github.com/kijai/ComfyUI-KwaiKolorsWrapper)'s repo, thanks for their contribution.
|
||||
|
||||
|
||||
@@ -37,10 +37,12 @@
|
||||
- 支持Stable Diffusion 3 多账号API节点
|
||||
- 支持IC-Light的应用 [示例参考](https://github.com/yolain/ComfyUI-Yolain-Workflows?tab=readme-ov-file#2-5-ic-light) | [代码整合来源](https://github.com/huchenlei/ComfyUI-IC-Light) | [技术参考](https://github.com/lllyasviel/IC-Light)
|
||||
- 中文提示词自动识别,使用[opus-mt-zh-en模型](https://huggingface.co/Helsinki-NLP/opus-mt-zh-en)
|
||||
- 支持 sd3 模型
|
||||
- 支持 sd3 模型
|
||||
- 支持 kolors 模型
|
||||
|
||||
## 安装
|
||||
将存储库克隆到 **custom_nodes** 目录并安装依赖
|
||||
|
||||
1. 将存储库克隆到 **custom_nodes** 目录并安装依赖
|
||||
```shell
|
||||
#1. git下载
|
||||
git clone https://github.com/yolain/ComfyUI-Easy-Use
|
||||
@@ -48,10 +50,12 @@ git clone https://github.com/yolain/ComfyUI-Easy-Use
|
||||
双击install.bat安装依赖
|
||||
```
|
||||
|
||||
|
||||
## 更新日志
|
||||
|
||||
**v1.2.1**
|
||||
|
||||
- 增加 `easy controlnetLoader++`
|
||||
- `easy ipadapterApply` 和 `easy ipadapterApplyADV` 增加 **PLUS (kolors genernal)** 预置项 (支持kolors IPA,可能会改名)
|
||||
- 去除 `easy positive` `easy negative` 等prompt节点的自动将中文翻译功能,自动翻译仅在 `easy a1111Loader` 等不支持中文TE的加载器中生效
|
||||
- 增加 `easy kolorsLoader` - 可灵加载器,参考了 [MinusZoneAI](https://github.com/MinusZoneAI/ComfyUI-Kolors-MZ) 和 [kijai](https://github.com/kijai/ComfyUI-KwaiKolorsWrapper) 的代码。
|
||||
|
||||
+75
-16
@@ -29,7 +29,7 @@ from .libs.utils import find_wildcards_seed, is_linked_styles_selector, easySave
|
||||
from .libs.loader import easyLoader
|
||||
from .libs.sampler import easySampler, alignYourStepsScheduler, gitsScheduler
|
||||
from .libs.xyplot import easyXYPlot
|
||||
from .libs.controlnet import easyControlnet
|
||||
from .libs.controlnet import easyControlnet, union_controlnet_types
|
||||
from .libs.conditioning import prompt_to_cond, set_cond
|
||||
from .libs.easing import EasingBase
|
||||
from .libs.translate import has_chinese, zh_to_en
|
||||
@@ -2209,8 +2209,6 @@ class loraStack:
|
||||
|
||||
class controlnetStack:
|
||||
|
||||
def get_file_list(filenames):
|
||||
return [file for file in filenames if file != "put_models_here.txt" and "lllite" not in file]
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -2227,7 +2225,7 @@ class controlnetStack:
|
||||
}
|
||||
|
||||
for i in range(1, max_cn_num+1):
|
||||
inputs["optional"][f"controlnet_{i}"] = (["None"] + s.get_file_list(folder_paths.get_filename_list("controlnet")), {"default": "None"})
|
||||
inputs["optional"][f"controlnet_{i}"] = (["None"] + folder_paths.get_filename_list("controlnet"), {"default": "None"})
|
||||
inputs["optional"][f"controlnet_{i}_strength"] = ("FLOAT", {"default": 1.0, "min": -10.0, "max": 10.0, "step": 0.01},)
|
||||
inputs["optional"][f"start_percent_{i}"] = ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001},)
|
||||
inputs["optional"][f"end_percent_{i}"] = ("FLOAT",{"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001},)
|
||||
@@ -2270,14 +2268,12 @@ class controlnetStack:
|
||||
class controlnetSimple:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
def get_file_list(filenames):
|
||||
return [file for file in filenames if file != "put_models_here.txt" and "lllite" not in file]
|
||||
|
||||
return {
|
||||
"required": {
|
||||
"pipe": ("PIPE_LINE",),
|
||||
"image": ("IMAGE",),
|
||||
"control_net_name": (get_file_list(folder_paths.get_filename_list("controlnet")),),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
},
|
||||
"optional": {
|
||||
"control_net": ("CONTROL_NET",),
|
||||
@@ -2293,9 +2289,9 @@ class controlnetSimple:
|
||||
FUNCTION = "controlnetApply"
|
||||
CATEGORY = "EasyUse/Loaders"
|
||||
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None, strength=1, scale_soft_weights=1):
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None, strength=1, scale_soft_weights=1, union_type=None):
|
||||
|
||||
positive, negative = easyControlnet().apply(control_net_name, image, pipe["positive"], pipe["negative"], strength, 0, 1, control_net, scale_soft_weights, None, easyCache)
|
||||
positive, negative = easyControlnet().apply(control_net_name, image, pipe["positive"], pipe["negative"], strength, 0, 1, control_net, scale_soft_weights, mask=None, easyCache=easyCache)
|
||||
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
@@ -2319,14 +2315,12 @@ class controlnetAdvanced:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
def get_file_list(filenames):
|
||||
return [file for file in filenames if file != "put_models_here.txt" and "lllite" not in file]
|
||||
|
||||
return {
|
||||
"required": {
|
||||
"pipe": ("PIPE_LINE",),
|
||||
"image": ("IMAGE",),
|
||||
"control_net_name": (get_file_list(folder_paths.get_filename_list("controlnet")),),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
},
|
||||
"optional": {
|
||||
"control_net": ("CONTROL_NET",),
|
||||
@@ -2347,7 +2341,71 @@ class controlnetAdvanced:
|
||||
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None, strength=1, start_percent=0, end_percent=1, scale_soft_weights=1):
|
||||
positive, negative = easyControlnet().apply(control_net_name, image, pipe["positive"], pipe["negative"],
|
||||
strength, start_percent, end_percent, control_net, scale_soft_weights, None, easyCache)
|
||||
strength, start_percent, end_percent, control_net, scale_soft_weights, union_type=None, mask=None, easyCache=easyCache)
|
||||
|
||||
new_pipe = {
|
||||
"model": pipe['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, positive, negative)
|
||||
|
||||
# controlnetPlusPlus
|
||||
class controlnetPlusPlus:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
|
||||
return {
|
||||
"required": {
|
||||
"pipe": ("PIPE_LINE",),
|
||||
"image": ("IMAGE",),
|
||||
"control_net_name": (folder_paths.get_filename_list("controlnet"),),
|
||||
},
|
||||
"optional": {
|
||||
"control_net": ("CONTROL_NET",),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||
"start_percent": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"end_percent": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001}),
|
||||
"scale_soft_weights": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.001},),
|
||||
"union_type": (list(union_controlnet_types.keys()),)
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("PIPE_LINE", "CONDITIONING", "CONDITIONING")
|
||||
RETURN_NAMES = ("pipe", "positive", "negative")
|
||||
OUTPUT_NODE = True
|
||||
|
||||
FUNCTION = "controlnetApply"
|
||||
CATEGORY = "EasyUse/Loaders"
|
||||
|
||||
|
||||
def controlnetApply(self, pipe, image, control_net_name, control_net=None, strength=1, start_percent=0, end_percent=1, scale_soft_weights=1, union_type=None):
|
||||
if scale_soft_weights < 1:
|
||||
if "ScaledSoftControlNetWeights" in NODE_CLASS_MAPPINGS:
|
||||
soft_weight_cls = NODE_CLASS_MAPPINGS['ScaledSoftControlNetWeights']
|
||||
(weights, timestep_keyframe) = soft_weight_cls().load_weights(scale_soft_weights, False)
|
||||
cn_adv_cls = NODE_CLASS_MAPPINGS['ACN_ControlNet++LoaderSingle']
|
||||
control_net, = cn_adv_cls().load_controlnet_plusplus(control_net_name, union_type)
|
||||
apply_adv_cls = NODE_CLASS_MAPPINGS['ACN_AdvancedControlNetApply']
|
||||
positive, negative, _ = apply_adv_cls().controlnetApply(pipe["positive"], pipe["negative"], control_net, image, strength, start_percent, end_percent, timestep_kf=timestep_keyframe,)
|
||||
else:
|
||||
raise Exception(
|
||||
f"[Advanced-ControlNet Not Found] you need to install 'COMFYUI-Advanced-ControlNet'")
|
||||
else:
|
||||
positive, negative = easyControlnet().apply(control_net_name, image, pipe["positive"], pipe["negative"],
|
||||
strength, start_percent, end_percent, control_net, scale_soft_weights, union_type=union_type, mask=None, easyCache=easyCache)
|
||||
|
||||
new_pipe = {
|
||||
"model": pipe['model'],
|
||||
@@ -3037,9 +3095,8 @@ class ipadapter:
|
||||
# 1. Load the clipvision model
|
||||
if not clip_vision:
|
||||
clipvision_file, clipvision_name = self.get_clipvision_file(preset, node_name)
|
||||
preset = preset.lower()
|
||||
if clipvision_file is None:
|
||||
if preset.startswith("plus (kolors"):
|
||||
if preset.lower().startswith("plus (kolors"):
|
||||
model_url = IPADAPTER_CLIPVISION_MODELS["clip-vit-large-patch14-336"]["model_url"]
|
||||
clipvision_file = get_local_filepath(model_url, IPADAPTER_DIR, "clip-vit-large-patch14-336.bin")
|
||||
else:
|
||||
@@ -3052,7 +3109,7 @@ class ipadapter:
|
||||
log_node_info("easy ipadapterApply", f"Using ClipVisonModel {clipvision_name} Cached")
|
||||
_, clip_vision = backend_cache.cache[clipvision_name][1]
|
||||
else:
|
||||
if preset.startswith("plus (kolors"):
|
||||
if preset.lower().startswith("plus (kolors"):
|
||||
from .kolors.loader import load_kolors_clip_vision
|
||||
clip_vision = load_kolors_clip_vision(clipvision_file)
|
||||
else:
|
||||
@@ -7492,6 +7549,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"easy controlnetStack": controlnetStack,
|
||||
"easy controlnetLoader": controlnetSimple,
|
||||
"easy controlnetLoaderADV": controlnetAdvanced,
|
||||
"easy controlnetLoader++": controlnetPlusPlus,
|
||||
"easy LLLiteLoader": LLLiteLoader,
|
||||
# Adapter 适配器
|
||||
"easy ipadapterApply": ipadapterApply,
|
||||
@@ -7610,6 +7668,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"easy controlnetStack": "EasyControlnetStack",
|
||||
"easy controlnetLoader": "EasyControlnet",
|
||||
"easy controlnetLoaderADV": "EasyControlnet (Advanced)",
|
||||
"easy controlnetLoader++": "EasyControlnet++",
|
||||
"easy LLLiteLoader": "EasyLLLite",
|
||||
# Adapter 适配器
|
||||
"easy ipadapterApply": "Easy Apply IPAdapter",
|
||||
|
||||
+12
-1
@@ -3,17 +3,28 @@ import comfy.controlnet
|
||||
import comfy.model_management
|
||||
from nodes import NODE_CLASS_MAPPINGS
|
||||
|
||||
union_controlnet_types = {"auto": -1, "openpose": 0, "depth": 1, "hed/pidi/scribble/ted": 2, "canny/lineart/anime_lineart/mlsd": 3, "normal": 4, "segment": 5, "tile": 6, "repaint": 7}
|
||||
|
||||
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, mask=None, easyCache=None, use_cache=True):
|
||||
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, union_type=None, easyCache=None, use_cache=True):
|
||||
if strength == 0:
|
||||
return (positive, negative)
|
||||
|
||||
if control_net is None:
|
||||
control_net = easyCache.load_controlnet(control_net_name, scale_soft_weights, use_cache)
|
||||
|
||||
# union controlnet
|
||||
if union_type is not None:
|
||||
control_net = control_net.copy()
|
||||
type_number = union_controlnet_types[union_type]
|
||||
if type_number >= 0:
|
||||
control_net.set_extra_arg("control_type", [type_number])
|
||||
else:
|
||||
control_net.set_extra_arg("control_type", [])
|
||||
|
||||
if mask is not None:
|
||||
mask = mask.to(self.device)
|
||||
|
||||
|
||||
@@ -2,10 +2,10 @@ import {app} from "../../../../scripts/app.js";
|
||||
import {$t} from '../common/i18n.js'
|
||||
import {CheckpointInfoDialog, LoraInfoDialog} from "../common/model.js";
|
||||
|
||||
const loaders = ['easy fullLoader', 'easy a1111Loader', 'easy comfyLoader', 'easy hunyuanDiTLoader', 'easy pixArtLoader']
|
||||
const loaders = ['easy fullLoader', 'easy a1111Loader', 'easy comfyLoader', 'easy kolorsLoader', 'easy hunyuanDiTLoader', 'easy pixArtLoader']
|
||||
const preSampling = ['easy preSampling', 'easy preSamplingAdvanced', 'easy preSamplingDynamicCFG', 'easy preSamplingNoiseIn', 'easy preSamplingCustom', 'easy preSamplingLayerDiffusion', 'easy fullkSampler']
|
||||
const kSampler = ['easy kSampler', 'easy kSamplerTiled', 'easy kSamplerInpainting', 'easy kSamplerDownscaleUnet', 'easy kSamplerLayerDiffusion']
|
||||
const controlnet = ['easy controlnetLoader', 'easy controlnetLoaderADV', 'easy instantIDApply', 'easy instantIDApplyADV']
|
||||
const controlnet = ['easy controlnetLoader', 'easy controlnetLoaderADV', 'easy controlnetLoader++', 'easy instantIDApply', 'easy instantIDApplyADV']
|
||||
const ipadapter = ['easy ipadapterApply', 'easy ipadapterApplyADV', 'easy ipadapterStyleComposition', 'easy ipadapterApplyFromParams', 'easy pulIDApply', 'easy pulIDApplyADV']
|
||||
const positive_prompt = ['easy positive', 'easy wildcards']
|
||||
const imageNode = ['easy loadImageBase64', 'LoadImage', 'LoadImageMask']
|
||||
|
||||
Reference in New Issue
Block a user