ComfyUI自定义节点插件开发教程
ComfyUI自定义节点插件开发教程
ComfyUI自定义节点插件开发教程 ComfyUI自定义节点插件开发教程 Modified October 29, 2024 Code block Python 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 自定义一个可运行的节点 Code block Python import random import torch import comfy.model management class runnable node: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:B example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { "required": { 2 左边的输入点在这里定义================================================= "左边的输入": ("STRING", {"forceInput": True}), 3 中间的参数栏在这里定义================================================= "参数:整数": ("INT", { "default": 20, 默认 "min": 1, "max": 10000, "step": 2, 步长 "display": "number"}), 数值调整 }, } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输出的数据类型,需要大写 RETURN TYPES = ("INT",) 自定义输出名称 RETURN NAMES = ("1个整数",) 5. 节点的核心功能逻辑在这里定义 FUNCTION = "test" 核心功能函数名称,将运行这个类中的这个方法 def run(self,): pass 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python from .example1 import A,B,C from .example1 import runnable node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node } 自定义一个二维码生成节点 QR二维码的项目地址:https://github.com/x hw/amazing qr 1. amzqr文件夹是该项目的核心代码,将其复制至自定义的插件文件夹下,并将代码做适当的修改调整,以适应插件 2. 安装QR二维码的项目的requirements.txt,并复制到自己的项目中(可选) Code block TypeScript pip install r requirements.txt 因为QR二维码项目里面的requirements.txt,comfyui的原生环境已经能满足,所以不用进行pip install r requirements.txt Code block Python import os from typing import Optional import numpy as np import torch from torchvision import transforms from PIL import Image from .amzqr.amzqr import run class QR node: def init (self) None: pass CATEGORY = "😀😀😀my custom plugin:QR example😀😀😀" @classmethod def INPUT TYPES(s): return { "required": { "url sentence": ("STRING", {"default": "https://github.com/", }), "version": ("INT", { "default": 5, "min": 1, "max": 40, "step": 1 }), "level": (["L", "M", "Q", "H"], { "default": "H" }), "colorized": ("BOOLEAN", {"default": False}), "contrast": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), "brightness": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), }, "optional": { "IMAGE": ("IMAGE", {"default": None}), } } OUTPUT NODE = True RETURN TYPES = ("IMAGE", ) 自定义输出名称 RETURN NAMES = ("IMAGE", ) FUNCTION的名称与函数名对应 FUNCTION = "generate QR" def generate QR(self, url sentence, version, level, colorized, contrast, brightness, IMAGE: Optional[torch.tensor]=None): """ 参数与上面的INPUT TYPES函数的return对应 IMAGE格式的图片必须转成tensor格式,维度(N, H, W, C)例如(1, 1024, 1024, 3) """ if IMAGE is not None: IMAGE = IMAGE.permute(0, 3, 1, 2) transform = transforms.ToPILImage() IMAGE = transform(IMAGE.squeeze(0)) directory=os.getcwd() , , image name = run(url sentence, version, level, IMAGE, colorized, contrast, brightness, save name="qr code.png", save dir=directory) image = Image.open(os.path.join(directory, image name)).convert("RGB") image tensor = transforms.ToTensor()(image) image tensor = image tensor.unsqueeze(0) image tensor = image tensor.permute(0, 2, 3, 1) 输出格式必须是tuple return (image tensor, ) Code block Python from .example1 import A from .example2 import B from .example3 import C from .example4 import runnable node from .QR import QR node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node, "QR node": QR node, } 生成的二维码可以使用浏览器进行扫描 Code block Python 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 自定义一个可运行的节点 Code block Python import random import torch import comfy.model management class runnable node: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:B example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { "required": { 2 左边的输入点在这里定义================================================= "左边的输入": ("STRING", {"forceInput": True}), 3 中间的参数栏在这里定义================================================= "参数:整数": ("INT", { "default": 20, 默认 "min": 1, "max": 10000, "step": 2, 步长 "display": "number"}), 数值调整 }, } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输出的数据类型,需要大写 RETURN TYPES = ("INT",) 自定义输出名称 RETURN NAMES = ("1个整数",) 5. 节点的核心功能逻辑在这里定义 FUNCTION = "test" 核心功能函数名称,将运行这个类中的这个方法 def run(self,): pass 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python from .example1 import A,B,C from .example1 import runnable node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node } Code block Python import random import torch import comfy.model management class runnable node: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:B example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { "required": { 2 左边的输入点在这里定义================================================= "左边的输入": ("STRING", {"forceInput": True}), 3 中间的参数栏在这里定义================================================= "参数:整数": ("INT", { "default": 20, 默认 "min": 1, "max": 10000, "step": 2, 步长 "display": "number"}), 数值调整 }, } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输出的数据类型,需要大写 RETURN TYPES = ("INT",) 自定义输出名称 RETURN NAMES = ("1个整数",) 5. 节点的核心功能逻辑在这里定义 FUNCTION = "test" 核心功能函数名称,将运行这个类中的这个方法 def run(self,): pass 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python from .example1 import A,B,C from .example1 import runnable node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node } 自定义一个二维码生成节点 QR二维码的项目地址:https://github.com/x hw/amazing qr 1. amzqr文件夹是该项目的核心代码,将其复制至自定义的插件文件夹下,并将代码做适当的修改调整,以适应插件 2. 安装QR二维码的项目的requirements.txt,并复制到自己的项目中(可选) 因为QR二维码项目里面的requirements.txt,comfyui的原生环境已经能满足,所以不用进行pip install r requirements.txt Code block Python import os from typing import Optional import numpy as np import torch from torchvision import transforms from PIL import Image from .amzqr.amzqr import run class QR node: def init (self) None: pass CATEGORY = "😀😀😀my custom plugin:QR example😀😀😀" @classmethod def INPUT TYPES(s): return { "required": { "url sentence": ("STRING", {"default": "https://github.com/", }), "version": ("INT", { "default": 5, "min": 1, "max": 40, "step": 1 }), "level": (["L", "M", "Q", "H"], { "default": "H" }), "colorized": ("BOOLEAN", {"default": False}), "contrast": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), "brightness": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), }, "optional": { "IMAGE": ("IMAGE", {"default": None}), } } OUTPUT NODE = True RETURN TYPES = ("IMAGE", ) 自定义输出名称 RETURN NAMES = ("IMAGE", ) FUNCTION的名称与函数名对应 FUNCTION = "generate QR" def generate QR(self, url sentence, version, level, colorized, contrast, brightness, IMAGE: Optional[torch.tensor]=None): """ 参数与上面的INPUT TYPES函数的return对应 IMAGE格式的图片必须转成tensor格式,维度(N, H, W, C)例如(1, 1024, 1024, 3) """ if IMAGE is not None: IMAGE = IMAGE.permute(0, 3, 1, 2) transform = transforms.ToPILImage() IMAGE = transform(IMAGE.squeeze(0)) directory=os.getcwd() , , image name = run(url sentence, version, level, IMAGE, colorized, contrast, brightness, save name="qr code.png", save dir=directory) image = Image.open(os.path.join(directory, image name)).convert("RGB") image tensor = transforms.ToTensor()(image) image tensor = image tensor.unsqueeze(0) image tensor = image tensor.permute(0, 2, 3, 1) 输出格式必须是tuple return (image tensor, ) Code block Python from .example1 import A from .example2 import B from .example3 import C from .example4 import runnable node from .QR import QR node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node, "QR node": QR node, } Code block Python import os from typing import Optional import numpy as np import torch from torchvision import transforms from PIL import Image from .amzqr.amzqr import run class QR node: def init (self) None: pass CATEGORY = "😀😀😀my custom plugin:QR example😀😀😀" @classmethod def INPUT TYPES(s): return { "required": { "url sentence": ("STRING", {"default": "https://github.com/", }), "version": ("INT", { "default": 5, "min": 1, "max": 40, "step": 1 }), "level": (["L", "M", "Q", "H"], { "default": "H" }), "colorized": ("BOOLEAN", {"default": False}), "contrast": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), "brightness": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 3.0, "step": 0.01}), }, "optional": { "IMAGE": ("IMAGE", {"default": None}), } } OUTPUT NODE = True RETURN TYPES = ("IMAGE", ) 自定义输出名称 RETURN NAMES = ("IMAGE", ) FUNCTION的名称与函数名对应 FUNCTION = "generate QR" def generate QR(self, url sentence, version, level, colorized, contrast, brightness, IMAGE: Optional[torch.tensor]=None): """ 参数与上面的INPUT TYPES函数的return对应 IMAGE格式的图片必须转成tensor格式,维度(N, H, W, C)例如(1, 1024, 1024, 3) """ if IMAGE is not None: IMAGE = IMAGE.permute(0, 3, 1, 2) transform = transforms.ToPILImage() IMAGE = transform(IMAGE.squeeze(0)) directory=os.getcwd() , , image name = run(url sentence, version, level, IMAGE, colorized, contrast, brightness, save name="qr code.png", save dir=directory) image = Image.open(os.path.join(directory, image name)).convert("RGB") image tensor = transforms.ToTensor()(image) image tensor = image tensor.unsqueeze(0) image tensor = image tensor.permute(0, 2, 3, 1) 输出格式必须是tuple return (image tensor, ) Code block Python from .example1 import A from .example2 import B from .example3 import C from .example4 import runnable node from .QR import QR node NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A, "funtion B": B, "funtion C": C, "runnable node": runnable node, "QR node": QR node, } 生成的二维码可以使用浏览器进行扫描 PS: 自定义节点时可以参考ComfyUI windows portable\ComfyUI\extra model paths.yaml.example和ComfyUI windows portable\ComfyUI\nodes.py 🍞 原作者:说谁胖呢 原始链接 https://github.com/Pal dont want to work/comfyui custom nodes tutorial 原作者:说谁胖呢 原始链接 https://github.com/Pal dont want to work/comfyui custom nodes tutorial 准备工作 1. 下载最新的comfyui安装包,里面不包含任何节点,启动省时间,debug方便 https://github.com/comfyanonymous/ComfyUI 2. 解压文件并双击运行run nvidia gpu.bat,可以看见comfyui 界面 自定义comfyui custom nodes 自定义节点(初级) 1. 在custom node文件夹新建一个文件夹 2. 创建一个python文件(example1.py),同时包含 init .py Code block Python 1.定义一个类A,一个节点就是一个类。comfyui会引入这个类作为一个节点 class A: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:A example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输出的数据类型,需要大写 RETURN TYPES = ("INT",) 自定义输出名称 RETURN NAMES = ("1个整数",) 5. 节点的核心功能逻辑在这里定义 FUNCTION = "test" 核心功能函数名称,将运行这个类中的这个方法 def test(self,): pass 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python from .example1 import A 注意:必须要有. NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A } Code block Python 1.定义一个类A,一个节点就是一个类。comfyui会引入这个类作为一个节点 class A: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:A example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输出的数据类型,需要大写 RETURN TYPES = ("INT",) 自定义输出名称 RETURN NAMES = ("1个整数",) 5. 节点的核心功能逻辑在这里定义 FUNCTION = "test" 核心功能函数名称,将运行这个类中的这个方法 def test(self,): pass 注意:以上代码,只代表了该节点的功能,还需要通过 init .py引入 Code block Python from .example1 import A 注意:必须要有. NODE CLASS MAPPINGS = { "ui界面搜索节点名称": 对应实现的代码(类) "funtion A": A } 3. 启动run nvidia gpu.bat,搜索funtion A 看到上述界面即成功定义一个简单的节点 自定义节点(输入+输出) 1. 添加节点左侧输入和节点栏参数 在example1.py的基础上再定义一个类B Code block Python 1.定义一个类B,一个节点就是一个类。comfyui会引入这个类作为一个节点 class B: def init (self): pass 2. 使用关键的标识符来表示该节点 CATEGORY = "😀😀😀my custom plugin:B example😀😀😀" 3.节点左侧输入 @classmethod def INPUT TYPES(s): 固定格式,输入参数种类 返回一个包含所需输入类型的字典,这里暂时不定义输入!!! return { "required": { 定义节点左侧输入 "左边的输入": ("STRING", {"forceInput": True}), 定义节点栏内参数 "参数:整数": ("INT", { "default": 20, 默认 "min": 1, "max": 10000, "step": 2, 步长 "display": "number"}), 数值调整 }, } 4.节点右侧输出 OUTPUT NODE = True 表明它是一个输出节点 输