diff --git a/README.en.md b/README.en.md index 2d49250..372e2fb 100644 --- a/README.en.md +++ b/README.en.md @@ -56,9 +56,10 @@ Double-click install.bat to install the required dependencies **v1.2.1** +- Added `easy ipadapterApplyFaceIDKolors` - Added **inspyrenet** to `easy imageRemBg` - Added `easy controlnetLoader++` -- Added **PLUS (kolors genernal)** preset to `easy ipadapterApply` and `easy ipadapterApplyADV` (Supported kolors ipadapter) +- Added **PLUS (kolors genernal)** and **FACEID PLUS KOLORS** 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. **v1.2.0** diff --git a/README.md b/README.md index 3a7dde5..3669499 100644 --- a/README.md +++ b/README.md @@ -64,9 +64,10 @@ git clone https://github.com/yolain/ComfyUI-Easy-Use **v1.2.1** +- 增加 `easy ipadapterApplyFaceIDKolors` +- `easy ipadapterApply` 和 `easy ipadapterApplyADV` 增加 **PLUS (kolors genernal)** 和 **FACEID PLUS KOLORS** 预置项 - `easy imageRemBg` 增加 **inspyrenet** 选项 - 增加 `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) 的代码。 diff --git a/py/easyNodes.py b/py/easyNodes.py index 3798cd5..dd9b9c0 100644 --- a/py/easyNodes.py +++ b/py/easyNodes.py @@ -2919,7 +2919,7 @@ class ipadapter: is_insightface = True elif preset.startswith("faceid plus kolors"): if is_sdxl: - pattern = '(kolors|ipa).faceid.plus\.(safetensors|bin)$' + pattern = '(kolors.ip.adapter.faceid.plus|ipa.faceid.plus)\.(safetensors|bin)$' else: raise Exception("faceid plus kolors model is not supported for SD1.5") is_insightface = True @@ -2992,6 +2992,7 @@ class ipadapter: model_keys = model.keys() if "adapter_modules" in model_keys: model["ip_adapter"] = model["adapter_modules"] + model["faceidplusv2"] = True del model['adapter_modules'] if not "ip_adapter" in model_keys or not model["ip_adapter"]: @@ -3122,7 +3123,7 @@ class ipadapterApply(ipadapter): CATEGORY = "EasyUse/Adapter" FUNCTION = "apply" - def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, start_at, end_at, cache_mode, use_tiled, attn_mask=None, optional_ipadapter=None): + def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, start_at, end_at, cache_mode, use_tiled, attn_mask=None, optional_ipadapter=None, weight_kolors=None): images, masks = image, [None] model, ipadapter = self.load_model(model, preset, lora_strength, provider, clip_vision=None, optional_ipadapter=optional_ipadapter, cache_mode=cache_mode) if use_tiled and preset not in self.faceid_presets: @@ -3135,7 +3136,9 @@ class ipadapterApply(ipadapter): if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS: self.error() cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"] - model, images = cls().apply_ipadapter(model, ipadapter, start_at=start_at, end_at=end_at, weight=weight, weight_type="linear", combine_embeds="concat", weight_faceidv2=weight_faceidv2, image=image, image_negative=None, clip_vision=None, attn_mask=attn_mask, insightface=None, embeds_scaling='V only') + if weight_kolors is None: + weight_kolors = weight + model, images = cls().apply_ipadapter(model, ipadapter, start_at=start_at, end_at=end_at, weight=weight, weight_type="linear", combine_embeds="concat", weight_faceidv2=weight_faceidv2, image=image, image_negative=None, clip_vision=None, attn_mask=attn_mask, insightface=None, embeds_scaling='V only', weight_kolors=weight_kolors) else: if "IPAdapter" not in ALL_NODE_CLASS_MAPPINGS: self.error() @@ -3189,14 +3192,18 @@ class ipadapterApplyAdvanced(ipadapter): CATEGORY = "EasyUse/Adapter" FUNCTION = "apply" - def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, weight_type, combine_embeds, start_at, end_at, embeds_scaling, cache_mode, use_tiled, use_batch, sharpening, weight_style=1.0, weight_composition=1.0, image_style=None, image_composition=None, expand_style=False, image_negative=None, clip_vision=None, attn_mask=None, optional_ipadapter=None, layer_weights=None): + def apply(self, model, image, preset, lora_strength, provider, weight, weight_faceidv2, weight_type, combine_embeds, start_at, end_at, embeds_scaling, cache_mode, use_tiled, use_batch, sharpening, weight_style=1.0, weight_composition=1.0, image_style=None, image_composition=None, expand_style=False, image_negative=None, clip_vision=None, attn_mask=None, optional_ipadapter=None, layer_weights=None, weight_kolors=None): images, masks = image, [None] model, ipadapter = self.load_model(model, preset, lora_strength, provider, clip_vision=clip_vision, optional_ipadapter=optional_ipadapter, cache_mode=cache_mode) + + if weight_kolors is None: + weight_kolors = weight + if layer_weights: if "IPAdapterMS" not in ALL_NODE_CLASS_MAPPINGS: self.error() cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"] - model, images = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, weight_style=weight_style, weight_composition=weight_composition, image_style=image_style, image_composition=image_composition, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling, layer_weights=layer_weights) + model, images = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, weight_style=weight_style, weight_composition=weight_composition, image_style=image_style, image_composition=image_composition, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling, layer_weights=layer_weights, weight_kolors=weight_kolors) elif use_tiled: if use_batch: if "IPAdapterTiledBatch" not in ALL_NODE_CLASS_MAPPINGS: @@ -3216,11 +3223,48 @@ class ipadapterApplyAdvanced(ipadapter): if "IPAdapterAdvanced" not in ALL_NODE_CLASS_MAPPINGS: self.error() cls = ALL_NODE_CLASS_MAPPINGS["IPAdapterAdvanced"] - model, images = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, weight_style=1.0, weight_composition=1.0, image_style=image_style, image_composition=image_composition, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling) + model, images = cls().apply_ipadapter(model, ipadapter, weight=weight, weight_type=weight_type, start_at=start_at, end_at=end_at, combine_embeds=combine_embeds, weight_faceidv2=weight_faceidv2, image=image, image_negative=image_negative, weight_style=1.0, weight_composition=1.0, image_style=image_style, image_composition=image_composition, expand_style=expand_style, clip_vision=clip_vision, attn_mask=attn_mask, insightface=None, embeds_scaling=embeds_scaling, weight_kolors=weight_kolors) if images is None: images = image return (model, images, masks, ipadapter) +class ipadapterApplyFaceIDKolors(ipadapterApplyAdvanced): + + @classmethod + def INPUT_TYPES(cls): + ipa_cls = cls() + presets = ipa_cls.presets + weight_types = ipa_cls.weight_types + return { + "required": { + "model": ("MODEL",), + "image": ("IMAGE",), + "preset": (['FACEID PLUS KOLORS'], {"default":"FACEID PLUS KOLORS"}), + "lora_strength": ("FLOAT", {"default": 0.6, "min": 0, "max": 1, "step": 0.01}), + "provider": (["CPU", "CUDA", "ROCM", "DirectML", "OpenVINO", "CoreML"],), + "weight": ("FLOAT", {"default": 0.8, "min": -1, "max": 3, "step": 0.05}), + "weight_faceidv2": ("FLOAT", {"default": 1.0, "min": -1, "max": 5.0, "step": 0.05}), + "weight_kolors": ("FLOAT", {"default": 0.8, "min": -1, "max": 5.0, "step": 0.05}), + "weight_type": (weight_types,), + "combine_embeds": (["concat", "add", "subtract", "average", "norm average"],), + "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}), + "embeds_scaling": (['V only', 'K+V', 'K+V w/ C penalty', 'K+mean(V) w/ C penalty'],), + "cache_mode": (["insightface only", "clip_vision only", "ipadapter only", "all", "none"], {"default": "all"},), + "use_tiled": ("BOOLEAN", {"default": False},), + "use_batch": ("BOOLEAN", {"default": False},), + "sharpening": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.05}), + }, + + "optional": { + "image_negative": ("IMAGE",), + "attn_mask": ("MASK",), + "clip_vision": ("CLIP_VISION",), + "optional_ipadapter": ("IPADAPTER",), + } + } + + class ipadapterStyleComposition(ipadapter): def __init__(self): super().__init__() @@ -7500,6 +7544,7 @@ NODE_CLASS_MAPPINGS = { # Adapter 适配器 "easy ipadapterApply": ipadapterApply, "easy ipadapterApplyADV": ipadapterApplyAdvanced, + "easy ipadapterApplyFaceIDKolors": ipadapterApplyFaceIDKolors, "easy ipadapterApplyEncoder": ipadapterApplyEncoder, "easy ipadapterApplyEmbeds": ipadapterApplyEmbeds, "easy ipadapterApplyRegional": ipadapterApplyRegional, @@ -7620,6 +7665,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { # Adapter 适配器 "easy ipadapterApply": "Easy Apply IPAdapter", "easy ipadapterApplyADV": "Easy Apply IPAdapter (Advanced)", + "easy ipadapterApplyFaceIDKolors": "Easy Apply IPAdapter (FaceID Kolors)", "easy ipadapterStyleComposition": "Easy Apply IPAdapter (StyleComposition)", "easy ipadapterApplyEncoder": "Easy Apply IPAdapter (Encoder)", "easy ipadapterApplyRegional": "Easy Apply IPAdapter (Regional)", diff --git a/web/js/easy/easyDynamicWidgets.js b/web/js/easy/easyDynamicWidgets.js index 478860c..dc5bc1c 100644 --- a/web/js/easy/easyDynamicWidgets.js +++ b/web/js/easy/easyDynamicWidgets.js @@ -287,6 +287,7 @@ function widgetLogic(node, widget) { toggleWidget(node, findWidgetByName(node, 'lora_strength')) toggleWidget(node, findWidgetByName(node, 'provider')) toggleWidget(node, findWidgetByName(node, 'weight_faceidv2')) + toggleWidget(node, findWidgetByName(node, 'weight_kolors')) toggleWidget(node, findWidgetByName(node, 'use_tiled'), true) let use_tiled = findWidgetByName(node, 'use_tiled') if(use_tiled && use_tiled.value){ @@ -297,11 +298,8 @@ function widgetLogic(node, widget) { } else if(faceid_presets.includes(widget.value)){ - if(['FACEID PLUS V2','FACEID PLUS KOLORS'].includes(widget.value)){ - toggleWidget(node, findWidgetByName(node, 'weight_faceidv2'), true) - }else{ - toggleWidget(node, findWidgetByName(node, 'weight_faceidv2')) - } + toggleWidget(node, findWidgetByName(node, 'weight_faceidv2'), ['FACEID PLUS V2','FACEID PLUS KOLORS'].includes(widget.value) ? true : false); + toggleWidget(node, findWidgetByName(node, 'weight_kolors'), ['FACEID PLUS KOLORS'].includes(widget.value) ? true : false); if(['FACEID PLUS KOLORS','FACEID PORTRAIT (style transfer)','FACEID PORTRAIT UNNORM - SDXL only (strong)'].includes(widget.value)){ toggleWidget(node, findWidgetByName(node, 'lora_strength'), false) } @@ -744,6 +742,7 @@ app.registerExtension({ case 'easy icLightApply': case 'easy ipadapterApply': case 'easy ipadapterApplyADV': + case 'easy ipadapterApplyFaceIDKolors': case 'easy ipadapterApplyEncoder': case 'easy applyInpaint': getSetters(node) diff --git a/web/js/easy/easyExtraMenu.js b/web/js/easy/easyExtraMenu.js index d28e6bf..b4ea61f 100644 --- a/web/js/easy/easyExtraMenu.js +++ b/web/js/easy/easyExtraMenu.js @@ -6,7 +6,7 @@ const loaders = ['easy fullLoader', 'easy a1111Loader', 'easy comfyLoader', 'eas 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 controlnetLoader++', 'easy instantIDApply', 'easy instantIDApplyADV'] -const ipadapter = ['easy ipadapterApply', 'easy ipadapterApplyADV', 'easy ipadapterStyleComposition', 'easy ipadapterApplyFromParams', 'easy pulIDApply', 'easy pulIDApplyADV'] +const ipadapter = ['easy ipadapterApply', 'easy ipadapterApplyADV', 'easy ipadapterApplyFaceIDKolors', 'easy ipadapterStyleComposition', 'easy ipadapterApplyFromParams', 'easy pulIDApply', 'easy pulIDApplyADV'] const positive_prompt = ['easy positive', 'easy wildcards'] const imageNode = ['easy loadImageBase64', 'LoadImage', 'LoadImageMask'] const inpaint = ['easy applyBrushNet', 'easy applyPowerPaint', 'easy applyInpaint'] diff --git a/web/js/easy/easySuggestion.js b/web/js/easy/easySuggestion.js index ca1b8d9..76dbf34 100644 --- a/web/js/easy/easySuggestion.js +++ b/web/js/easy/easySuggestion.js @@ -8,7 +8,7 @@ const preSamplingNodes = ["easy preSampling", "easy preSamplingAdvanced", "easy const kSampler = ["easy kSampler", "easy kSamplerTiled","easy kSamplerInpainting", "easy kSamplerDownscaleUnet", "easy kSamplerSDTurbo"] const controlNetNodes = ["easy controlnetLoader", "easy controlnetLoaderADV"] const instantIDNodes = ["easy instantIDApply", "easy instantIDApplyADV"] -const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV" , "easy ipadapterStyleComposition"] +const ipadapterNodes = ["easy ipadapterApply", "easy ipadapterApplyADV" ,"easy ipadapterApplyFaceIDKolors", "easy ipadapterStyleComposition"] const pipeNodes = ['easy pipeIn','easy pipeOut', 'easy pipeEdit'] const xyNodes = ['easy XYPlot', 'easy XYPlotAdvanced'] const extraNodes = ['easy setNode']