Nodes (47)
Let the graph pick the input, not you
QG_BoolToggle
QG_CanvasLabel
Six sliders, in the order a colourist actually reaches for them
Stop re-generating to fix a colour problem
Peek at anything mid-graph without breaking the wire
Two nodes and two wires, collapsed into one
The \"did anything actually arrive?\" check ComfyUI makes weirdly hard
QG_ExportImage
Google Translate in your prompt line, no API key required
An if/else that skips the branch you didn't pick
Stop flapping between two preview nodes
Crop, straighten and pad on the canvas — and get the mask for free
Grid assembly that skips the black frames
Reading size off an image, mask or latent
Resize with crop, pad or contain — and get the real numbers back
Watermarking inside the workflow, instead of exporting to Photoshop
The QG LoRA Loader Actually Earns Its Canvas Space
QG_MarkdownNote
Paint a mask a flat colour, so you can actually see it
Left-right or top-bottom, no maths
QG_Math
Prompt files on disk, loaded as text — no retyping
QG_Number Saves You the Choice
A kill switch for one wire, not the whole graph
A stopwatch on the canvas, so you know what that change cost
One seed, several samplers, and a way to get the good one back
Pick a ratio, get a latent — with the channel count you actually need
A LoRA strength control that behaves like one
QG_StringSwitch
QG_TextConcat
A text box on the canvas that behaves like a text box
Draw text into the pixels — and get a text-shaped mask out
Find and replace across a whole batch of prompts
Cut the thinking out of a model's output before it reaches your prompt
Stop Pasting Three Loader Nodes Into Every Workflow
QG Workflow Note
QG Workflow Switches
ComfyUI-QG-tools
一个 ComfyUI 自定义节点包,目前包含四十七个节点:LoRA 加载器、模型加载器(三合一)、 图像裁剪 + 旋转 + 补边、加载图像、工作流说明卡、工作流开关、运行计时器、文本、 加载文档、Google 翻译、任意切换、展示任意、是否判断、存在判断、 路由阻断、字符串切换、布尔开关、 数值、数值滑条、数学运算、颜色校正、颜色匹配、图像缩放、 图像或 Latent 尺寸、种子、图像水印、文字叠加图像、宫格图像拼接、 图像对比、导出图像、遮罩上色、遮罩拼接、遮罩精修、 遮罩裁剪、裁剪恢复、遮罩对齐、重绘裁剪、重绘缝合、 文本合并、文本替换、文本按分隔符分割、 尺寸选择器、空 Latent 分辨率、画布标签、Markdown 便签、释放显存、采样预览。
哪些是本插件原创、哪些搬自别的插件(连上游节点名和许可证):见下方 节点来源 一节,每个节点章节标题下也单独标了一行。
Image Crop + Rotate + Pad —— 在节点上直接把画面摆正、裁好、补出画布
- 看得见地编辑 —— 节点上就是一块编辑面板:拖动画面旋转、拖角裁切、拖边补边,不用来回改参数
- 补出来的地方自动进遮罩 —— 新补的边、旋转留下的角、原图里透明的地方都算「待生成区域」,一路
mask输出 - 附带缝合器 ——
stitcher输出把生成结果贴回原图,接下游的缝合节点即可 - 能出规则尺寸 —— 「Divisible by」让输出的长宽能被 8/16/32 整除,模型和 VAE 都开心
LoRA Loader —— 把整摞 LoRA 收进一个节点里管
- 一次加一批 —— 选择框里每个文件都带勾选框:Ctrl 点逐个勾、Shift 点一段,底部一次加入;已经在栈里的文件自动标灰,不给重复勾
- 自动补 Civitai 封面图 —— 查 Civitai 信息时顺带把第一张图存成预览,之后悬停就能看到;分级可调,你自己放的图永远不会被覆盖
- 一个节点管整摞 LoRA —— 列表式的行编辑器,每行能搜文件、拖着调强度、随时开关、拖动排序
- 触发词自动汇总 —— 所有启用行的触发词去重后拼成一路字符串输出,直接接进提示词
- 整摞存成模板 —— 常用的 LoRA 组合存下来,在任何同类节点上一键套用
- 吸收模型链上的 LoRA —— 把串在模型链上下游的其它 LoRA 加载器全部并进来,原节点自动旁通,出图结果不变
模型加载器 —— 三合一:扩散模型 + CLIP + VAE 一次选完
- 一个节点顶掉「UNET Loader + Load CLIP + Load VAE」三个节点,输出标准
MODEL/CLIP/VAE - 下拉列表从本机现读,不绑模型家族;节点上只显示短文件名,不会把画布撑宽
Workflow Note —— 让别人打开你的工作流就知道怎么用
- 卡片式说明:大标题 + Markdown 正文 + 作者 + 链接,直接画在节点上
- 列出需要的模型和依赖的节点包,自动和本机安装对照,每行标出「✓ 已安装 / 缺失」,并给下载按钮
- 一键「从当前工作流检测」,把图里用到的所有自定义节点包列出来
Workflow Switches —— 一张卡片集中开关工作流
- 选中若干节点 → 建一个开关,一键旁通/恢复这一整块(比如「放大 + 保存」这套)
- 也能当参数预设用:为「开」和「关」各存一套选中节点的设置值,一键切换
- 折叠后只剩标签和开关,不占画布
Run Timer —— 这次跑图花了多久,直接写在画布上
- 整轮队列的秒表:开始跑就走字,跑完停住总时长
- 右键看最近几次的记录,改完设置好和上一次对比
- 时间跟着工作流一起保存,别人打开你的图就知道作者那次跑了多久
Text —— 画布上的一块随手文本框
- 手动敲的字,整段作为一路字符串输出,接给任何下游文本输入
- 纯 Python 节点,零依赖、不加载模型
加载文档 —— 把 Markdown 文件读成一路文本
- 下拉里选一个文档(.md / .markdown / .txt 都行),节点上直接预览内容,可以切「渲染视图 / 纯文本视图」、放大看、一键复制
- 输出 STRING,接提示词框、CLIP Text Encode、说明卡都行
- 纯文本模式会剥掉
#、*、表格线这些标记,读起来像一句提示词;原样模式按文件原封不动输出 - 文件放在 ComfyUI 的
input目录(或它旁边的md/prompts目录),也可以直接在custom_path填绝对路径
Google 翻译 —— 用 Google 翻译把提示词译成另一种语言
-
选源语言(auto 自动识别)和目标语言,节点排队运行(按 Run)时就把
文本输出译成目标语言,可直接接 CLIP Text Encode / 提示词框 -
节点上有一个「手动翻译」按钮:开启
手动翻译开关后,按钮会把文本框里的文字就地翻成目标语言(不影响连线的自动翻译) -
零额外依赖:免费通道用 ComfyUI 核心自带的
requests直连 Google 接口,无需 API key;若设了环境变量GOOGLE_TRANSLATION_API_KEY,则自动改用官方、不限量的 Google Cloud Translation API -
免费通道 Google 可能对服务端 IP 限流(HTTP 429),限流或网络异常时节点会原样返回原文而不是报错,流水线不会断
-
任意切换 —— 把多个同类型输入并成一路,输出第一个非空、已连接的那个
-
展示任意 —— 在节点上直接预览任意输入(文本/图像/遮罩/音频/视频),并原样透传
-
是否判断 —— 布尔分支:为真走「真时」,为假走「假时」,没走的那路不求值;只接一路也能跑
-
存在判断 —— 有值就真、没值就假,同时把值原样传下去(可选输入没接也照跑)
-
路由阻断 —— 一条线路的总开关:通过时原样透传,阻断时置空或静默掐断下游,且打开后上游根本不求值
-
字符串切换 —— 两段提示词写在节点上,拨一下布尔就换,不用再拉两个文本节点
-
布尔开关 —— 整张节点就是一枚开关:大号「开 / 关」+ 可点的胶囊,扇出到多个下游条件
-
数值 —— 整数和浮点合一:一张卡片里一个可拖的数字框,类型在标题栏齿轮里切
-
数值滑条 —— 一根滑条挑一个数:开箱是 0–1 一格 0.1(正好接 LoRA 强度),范围和类型随时改
-
数学运算 —— 一行表达式算出一个数:
round(a / b * 2, 2)写在一张卡片上,a/b/c… 接上游 -
常用于接「兜底」:有高清模型就走它,没有就走普通版;节点上接几个、槽位自动增减
-
所有输入必须是同一类型(混接 IMAGE 和 LATENT 会报人话错误),全空时也会报错而不是把
None传给下游
图像缩放 —— 像素或百分比缩放,顺手裁切 / 补边
- 度量可选「像素」或「百分比」,适配方式三选一:
crop铺满后居中裁、pad放下后居中补、contain只缩不裁 - 宽或高填 0 就按另一边等比推算(此时按
contain处理) - 除了图像,还把结果的实际宽高当整数输出,可直接喂给下游的尺寸运算
图像或 Latent 尺寸 —— 接什么都告诉你宽高
- 输入是通配类型,IMAGE / MASK / LATENT 都能接;Latent 内部尺寸是除以 8 存的,这里自动乘回 8
- 输出 WIDTH / HEIGHT 两个整数,用来驱动按尺寸分流的节点
- 遮罩的各种形状都认 ——
(B,H,W)、(B,1,H,W)、(H,W)都读得对。ComfyUI 的ImageToMask和LoadImage给的都是三维(B,H,W),这是最常见的一种 - 没接线时宽高都给 0,不报错
自写。思路来自 rgthree-comfy 的
Image or Latent Size(MIT),10-30 重写:修掉 「只认四维张量」——原来接最常见的三维遮罩会得到 0×0,且不给任何提示。
种子 —— 一张卡片管住一个种子
- 大号数字框里直接改种子;「随机值 / 固定 / Step」一段决定每次排队之后它怎么变(Step 再点一下变 −1)
- 「新种子」抽一枚并固定、「用上次」把上次真跑过的种子填回来,
▾里是最近 8 枚跑过的种子 - 底下一行实时显示「上次运行」用的种子——随机值模式下框里已经是下一枚,靠后端回传的值才准
- 老工作流里
-1 / -2 / -3的写法,打开时自动翻译成「随机值 / Step +1 / Step −1」,连线不用重接
图像水印 —— 贴水印不用再开修图软件
- 水印可缩放(等比适配 / 按倍数 / 按指定宽高)、可九宫格锚点定位再加像素偏移、可旋转、可调透明程度
- 底图是批次时逐帧贴同一位置;接一张遮罩还能限定哪些区域不透出水印
- 修掉了上游透明度失效的 bug:带 alpha 的水印现在真的按透明程度混合,旋转后的边角也正常
文字叠加图像 —— 把字直接画进图里
- 选系统字体、字号、颜色(内置六色或自定义 RGB),横排 / 竖排随意,按中心点坐标定位
- 除了画好的图像,还输出文字形状的遮罩,方便后续只在有字的区域做处理
- 批次时每一帧都画同样的字(上游只画了第一帧)
- 中心点按笔画算,不按行高 —— 「中心 Y」写 300,看到的字就真的居中在 300。 ⚠️ 10-30 修好了这件事:以前按字体行高居中,笔画实际比设定值高约字号的 19% (100px 字号高 19px)。老工作流里的文字会因此整体下移
自写。思路来自 ComfyUI_Muye 的
TextOverlayImage(MIT),10-30 重写:文字改成按 实际笔画居中、空批次不再抛异常、color_rgb补上forceInput。
宫格图像拼接 —— 多图拼成一张,节点上直接看
- 最多 16 张,默认统一成第一张的尺寸、在格内等比居中不裁剪;可设格间间隙与背景色
剔除全黑帧开关:上游批次节点给未接输入补的黑图占位可以自动丢掉,也能关掉照常拼进去
遮罩上色 / 遮罩拼接 —— 遮罩的两件小工具
- 上色:内置六色或自定义 RGB 把遮罩区域涂成纯色,遮罩按 0.5 硬切;单张遮罩会应用到整批
- 拼接:两张遮罩左右 / 上下拼成一张,输出标准
(1, H, W);可开启尺寸统一,把小图拉到与大图同尺寸
文本替换 —— 一次配好三组替换
- 最多三组「查找 → 替换」,规则按 1 → 2 → 3 顺序生效,后一条看得到前一条的产物
- 默认字面、正则可选:字面模式下括号、点号、竖线都是普通字符,提示词里的
(red:1.3)能整段删掉; 切到正则模式可用\d+、\1反向引用,写错直接报错而不是悄悄退化 - 查找留空就跳过整组 —— 不是「在每个字之间插替换串」(
str.replace("", x)会干这事) - 正则模式下替换内容是模板 ——
\1是第 1 个分组,所以想原样插一个反斜杠得写两次:C:\temp会静默变成「C: + 制表符 + emp」,C:\xyz直接报错。要插 Windows 路径又不想 操心转义,就把那条规则换回字面模式 - 写错时报错会点名第几条规则、错在「查找内容」还是「替换内容」
自写。思路来自 Comfyroll 的
CR_TextReplace(MIT),10-30 重写:输出类型从任意改成STRING,正则模式替换内容的报错从原始英文改成点名到栏位。
文本按分隔符分割 —— 切掉思考块、拆段落
- 分隔符支持正则;默认
<think>正好用来切掉模型的思考块 - 三路输出:
全部段落(合集)、单条切分(选定那条输入的完整切分)、指定段落(第 N 段) - 三个序号各管各的 —— 列表序号设 0 只让「单条切分」空,「指定段落」照旧取它自己那一位
- 空的段落会被丢掉,所以序号数的是非空段:文本开头就带分隔符时,不会有空段把序号顶偏
- 正则里用了捕获组的话,分隔符本身会留在结果里(
(,)切a,b得a、,、b)—— 这是 Python 的re.split语义,需要连分隔符一起留下时才这么写
自写。思路来自 ComfyUI_Muye 的
TextSplitByDelimiterEnhanced(MIT),10-30 重写:修掉 「列表序号设 0 会把指定段落也清空」,非法正则的报错改成中文并点名分隔符。
文本合并 —— 两段文本拼成一段
- 就是
文本1 + 分隔符 + 文本2,原样拼接、不去空格;想要空格或换行就写进分隔符 - 两个文本都是输入槽,从上游连过来;分隔符是文本框,直接填(常用来插「,」「 」或换行)
- 只接一路也干净 —— 没接的那一路连同分隔符一起省掉。单接一段时结果就是那一段,
不会尾巴上多一个
-(也别指望靠它「补分隔符」) - 空文本仍算数 —— 接了线但是空字符串照样参与拼接,
空 + "-" + X还是-X。 「没接线」和「接了但是空」是两件事,这一点和别的拼接节点不一样 - 只有一路输出(上游声明了第二路「显示帮助」却从不返回值,这里删掉了)
自写。思路来自 Comfyroll 的
CR_TextConcatenate(MIT),10-30 重写:修掉 「只接一路时会多出孤零零的分隔符」,输出类型从任意改成STRING。
尺寸选择器 —— 选好比例,直接出空 Latent
- 预设分辨率 + 比例下拉,可选长边缩放、百万像素档、宽高对齐倍数、帧数(大于 0 即视频模型)
比例里选采用比例—— 用预设标签里写的那条比例。预设的像素往往只是近似 (2304×1280实际是 9:5,标签标的是16:9),选了它才会按真正的 16:9 算;填任意比例 用下面一行自定义比例(如2.39:1)- 潜在通道数可选 4 / 16 —— SD1.5 / SDXL 用 4,Flux / SD3 / 视频模型用 16
对齐倍数留 0 时不额外取整,但求解比例 / 百万像素 / 长边时仍保证 8 的倍数 —— latent 就是按 8 展开的,非 8 的倍数会被悄悄截断(节点报 1215、图只有 1208)- 修掉了上游两个 bug:通道数写死 16、以及比例填「无」时长边把宽高都套上导致画面变正方形
- 另外自己修了两个:比例会被「向上取整」带偏(16:9 曾算成 7:4);输出的 Latent 没声明 8 倍下采样,16 倍模型上出图会翻倍
空 Latent 分辨率 —— 比例 + 百万像素,一步出 latent
- 官方的「分辨率选择器」算宽高、「空 Latent」吃宽高,中间得连两根线;这个节点合成一步: 选比例、给百万像素,直接出空 latent,算好的宽高也一并送出去
- 尺寸算法与官方
ResolutionSelector逐行一致(同样的 sqrt 缩放、同样按 8 的倍数对齐), 128 组参数实测逐个相同 - 高级里能改对齐倍数(8 / 16 / 32 / 64),给别的模型留口子
- 节点上带一排预览(宽 × 高 + 百万像素),只在 Nodes 2.0 显示 —— 官方在经典画布下同样不画
图像对比 —— 一张面板对照 A 和 B
-
三种看图方式:
滑动(竖线跟着指针,左边 A 右边 B)、A、B -
指针离开后自动停在「结果」那张图上——哪一路是结果按连线判断(B 通常是从 A 改出来的那张)
-
A 原样从输出送出,所以这个节点可以夹在流程中间,不影响下游
-
当前版本:v0.9.11(支持 Nodes 2.0 / Vue 渲染)
-
节点:47 个(
LoRA 加载器/模型加载器/加载图像/图像裁剪 + 旋转 + 补边/工作流说明卡/工作流开关/运行计时器/文本/加载文档/Google 翻译/任意切换/展示任意/是否判断/存在判断/路由阻断/字符串切换/布尔开关/数值/数值滑条/数学运算/颜色校正/颜色匹配/图像缩放/图像或 Latent 尺寸/种子/图像水印/文字叠加图像/宫格图像拼接/图像对比/导出图像/遮罩上色/遮罩拼接/遮罩精修/遮罩裁剪/裁剪恢复/遮罩对齐/重绘裁剪/重绘缝合/文本合并/文本替换/文本按分隔符分割/尺寸选择器/空 Latent 分辨率/画布标签/Markdown 便签/释放显存/采样预览) -
分类:全部在
QG-tools下,九个子分类Loaders/Text/Logic/Display/Workflow/Mask/Retouch/Annotation/Image(中文界面上显示为 加载器 / 文本 / 逻辑 / 展示 / 工作流 / 遮罩 / 重绘 / 标注 / 图像) -
依赖:无额外 pip 包。只用 ComfyUI 运行期自带的模块(torch / numpy / PIL / PyAV / folder_paths / comfy.*);
scipy、pymatting用到了才用,缺了有内置回退,不报错。 -
许可证:GPL-3.0-or-later
安装
方式一:ComfyUI Manager
打开 ComfyUI Manager → Install Custom Nodes → 搜索 ComfyUI-QG-Tools。
这条要在插件发布到 Comfy Registry 之后才可用; 还没发布时请用下面的方式二 / 方式三。
方式二:git clone
cd <你的 ComfyUI 目录>/custom_nodes
git clone https://github.com/live1617/ComfyUI-QG-tools
方式三:手动下载
从 Releases 下载 zip,
解压到 custom_nodes/ 下,并确认目录名是 ComfyUI-QG-tools。
装完完整重启 ComfyUI,控制台应出现:
----------------------------------------------------------------------
QG-tools v0.9.11 | 47 nodes loaded | 9 categories
https://github.com/live1617/ComfyUI-QG-tools
----------------------------------------------------------------------
无需 pip install 任何东西。四十七个节点都在 QG-tools 分类下
(细分:Loaders / Text / Logic / Display / Workflow / Mask / Retouch / Annotation / Image,
中文界面显示为 加载器 / 文本 / 逻辑 / 展示 / 工作流 / 遮罩 / 重绘 / 标注 / 图像),
节点标题按界面语言显示(中文界面 图像水印、英文界面 Image Watermark),
搜索 lora、crop、note、switch、timer、text、load、
watermark、mask、size、compare 这些英文词一样找得到(见下面「中英文搜索」)。
<!-- QG-ORIGINS:START -->
节点来源(原创 / 搬运)
47 个节点 = 41 原创(其中 28 个参考上游思路重写、3 个搬自作者自有旧插件) + 6 搬运。
口径:原创看代码是不是自己写的,搬运看是不是整段抄的。
- 原创 —— 代码自己写:从零实现、参考别家的用法换个思路重写、把自己以前插件里的东西合并进来,三种都算
- 搬运 —— 整段照抄上游代码,只改类名 / 节点 ID / 分类 / 显示名 / 文案,逻辑一行没动
判据很简单:能不能指出某段代码是从上游原样搬来的 —— 指得出就是搬运,指不出、只是照着别人的思路自己实现,就是原创。参考对象记在 reference 里,算原创不等于隐去出处。
逐条对应关系也在 ORIGINS.json(机器可读)与 DEVELOPMENT.md「抽取来源」一节。
| 节点 ID | 显示名 | 类型 | 上游 / 说明 |
|---|---|---|---|
| QG_MaskRefine | Mask Refine | 原创 | 本插件自己写(参考 ComfyUI-AusBoss(MIT)「Mask Refine 🆎」的用法,代码重写);自写(10-30 换掉 v0.9.0 的搬运版):六步顺序、九个控件、两路输出全不变。🔴 收缩时画布外被当成白色 —— 上游用 max_pool2d 的默认 padding(-inf),取负之后等于「画布外是白的」,于是贴边的遮罩无论 expand 负到多少都一格不缩,实测整幅全 1 的遮罩 expand=-2 之后仍是全 1;现在按「画布外没有像素」处理,整幅收缩 2 就只剩中间 4x4,而不贴边的形状与旧实现逐位一致。🔴 四维遮罩直接报错 —— 官方写明 MASK 是 [H,W] 或 [B,C,H,W],上游只认前两种;现在单通道四维压成 [B,H,W](结果与三维逐位相同),多通道报错并说清几通道。另:补洞的泛洪传播必须一步一格(一次用大核会跨过遮罩圈墙,把墙里的洞也算成外面 → 补洞整个失效且不报错);无 scipy 的降级路径与 scipy 逐位一致(两条路径都验了);预览改为覆盖整批帧(原来只写第 0 帧,批量跑完无从核对);文件名改 uuid、失败改 logging(原来 print + 手拼 5 位随机后缀)。📌 刻意保留:_qg_mask_helpers.py 那份给裁剪/重绘用,仍走旧的边界语义 —— 六个节点在用它,改动要单独评估 |
| QG_ImageCropRotatePad | 图像裁剪 + 旋转 + 补边 | 原创 | 本插件自己写(参考 ComfyUI-AusBoss(MIT)「Image Crop + Rotate + Pad 🆎」的用法,代码重写);接口沿用 AusBoss(节点 ID / 槽名 / 控件组合),实现早就是自己的:这个文件只剩 192 行的壳(声明输入 → 调引擎 → 打包 7 路输出),像素运算全在自写的 _qg_transform_engine.py(586 行,24 个函数),另有 _qg_transform_inputs.py(241 行)与 _qg_inpaint_crop_helpers.py(1782 行)。10-30 核对后把标注从 ported 改成 original —— 按 FreeMemory 那条口径反过来也成立:代码主体是自己的就不该标搬运,标了是把原创率报低。引擎还被 QG_LoadImage 的遮罩编辑器共用,动它要连带验两条路 |
| QG_RunTimer | Run Timer | 原创 | 本插件自己写(参考 ComfyUI-AusBoss(MIT)「Run Timer 🆎」的用法,代码重写);接口沿用 AusBoss(节点 ID / 无输入无输出 / 属性键的存档结构),实现全部重写:后端只有 51 行声明(noop 永不执行 —— 无输出节点不进 prompt),读数的决策逻辑在 web/shared/run_timer.mjs、绘制在 web/run_timer/index.js。10-31 两处都重写后把标注从 ported 改成 original。上游那套「节点自发 run」过滤(ownRuns,为 MaskByTouch 的预览跑图准备的)本包没有对应节点,故不搬 |
| QG_TextEditOutput | Text | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「Text Edit Output」的用法,代码重写);自写(10-30 换掉 v0.6.0 的搬运版):ID / 输入名 / 显示名 / 输出形态全不变。刻意保留 OUTPUT_IS_LIST —— 输出是「只有一项的列表」,普通 STRING 消费者会被 ComfyUI 拆回标量,只有声明列表输入的节点才拿到列表,删掉会静默改变那些图;同一条也定义了「不切分」:三行文本是一个元素,那是它和 QG_TextSplit 的分界 |
| QG_ImageWatermark | 图像水印 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「AddImageWatermark」的用法,代码重写);v0.8.5 搬入,10-30 重写为自写实现 |
| QG_TextOverlayImage | 文字叠加图像 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「TextOverlayImage」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):ID / 八个输入 / 两路输出 / 六个内置颜色 / 横竖排 / 每帧都画 / 不做 IS_CHANGED 全不变,老存档照开。⚠️ 唯一一处可见的行为变化:文字位置。旧实现用 Pillow 的 anchor="mm",那是按字体行高(ascender..descender)居中,而字体的行高比字母本身高,实测 100px 字号下 "AB" 的笔画中心比设定的 y 高 19px(两行、竖排、中文都一样偏差),节点承诺的「按中心定位」是虚的。现在先 multiline_textbbox 量真实墨迹框再按框心偏移,六组实测偏差 ≤1px,且不随字号放大(30px/300px 都是 1px 内)。🔴 代价:老工作流里所有文字会下移约 19% 字号,之前手调 y 补偿过的要调回来 —— 但旧位置本来就是错的(用户 10-30 确认要修)。另修三处:① color_rgb 漏了 forceInput(通配输入不加,前端画一个填不出颜色的文本框);② 空批次以前抛 stack expects a non-empty TensorList —— 那段 if mask_out is None 的兜底永远轮不到,因为 stack 先炸了,现在空进空出;③ _FONT_INDEX 是赋值了从不读的死变量(索引故意每次 INPUT_TYPES 重建,新装字体免重启),删掉,_FONT_DIRS 保留缓存 |
| QG_ImageGrid | 宫格图像拼接 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「MuyeGridImageConcat」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):五个控件 / 自动行列几何(1→1x1、2→2x1、3~4→2x2、5~9→3 列、10~16→4 列)/ match_size 等比装入不裁 / 黑帧过滤 / 预览输出全不变,仍是 OUTPUT_NODE。🔴 核心缺陷:灰度图被压成 1 像素宽 —— 搬运版按第 0 维判 (H,W,C) 还是 (B,H,W),而灰度单图是 (H,W,1),第 0 维是高度 → 被当成批次,unsqueeze(-1) 后变 (64,64,1,1)、通道扩三倍成 (64,64,1,3)、再取第一帧就只剩一行(实测 64x64 的灰度进 → 1x64 出)。判据改成看最后一维(≤4 当通道维),与包内其他三维判据一致。同一个判据还修了反向错误:灰度批次 (B,H,W) 原来被当成一张图(实测 4x32x32 进 → 32x4 出),现在正常拆帧拼四格。另:两通道输入原来在画布赋值处崩(既不落 channels==1 也不落 >3),现在取第一通道当灰;drop_black 不再假设每个条目都是张量(列表套列表原来 AttributeError);全黑报错补一句「把剔除全黑关掉」;FUNCTION 改 execute。📌 刻意不改:drop_black 默认开、真黑帧也会被丢(批次节点拿 zeros 填空槽的历史原因),以及 MAX_IMAGES=16 / MAX_COLS=4 的截断。断言 tools/_check_image_grid.py(30 项) |
| QG_MaskColorize | 遮罩上色 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「MaskColorize」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):三个输入、六个内置色、0.5 硬切、输出全不变。🔴 核心缺陷:遮罩帧数比图像少时直接崩 —— 搬运版用 mask[:image.shape[0]] 处理帧数不等,遮罩短的时候等于没截,紧接着的乘法广播失败(实测 4 帧图配 2 帧遮罩 → The size of tensor a (4) must match the size of tensor b (2));现在短的按序重复补齐、长的截断。另修:① 通配输入 color_rgb 漏了 forceInput(前端会在画布上多画一个填不出颜色的文本框,本包第六处同款);② 遮罩与图像尺寸不一致时给中文错误并点名两边尺寸,原来是泛泛的广播错误;③ 三元组解析统一进 as_triple(),非数字不再 TypeError(原版 max(['a','b','c']) <= 1.0 直接炸),逐分量钳到 0-255(原版 [300,-20,0] 会漏出 300),张量输入不用逐元素走 Python;④ 不再 ones_like(image) * color 造一张整幅纯色图。📌 刻意不改:0-1 与 0-255 的歧义([1,0,0] 两档都说得通),规则仍是「三个都 ≤1 当 0-1」,只是写进 tooltip 而不是隐含 |
| QG_MaskConcat | 遮罩拼接 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「MaskConcatenate」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):四个控件、方向取值、单帧输出尺寸全不变。🔴 核心缺陷:批次被压成一条 —— 搬运版对 3 维遮罩用 mask.max(dim=0) 把 (B,H,W) 收成 (H,W),四帧进、一帧出,不报错不提示;现在原样保留 (B,H,W),两路帧数不同就短的重复补齐,B=1 时与搬运版逐字节一致。另修:混精度按 promote_types 取宽(原版按第一路 dtype 建画布,静默降位);不认识的 direction 值按左右拼(原版按左右算画布却只在严格等于 left-right 时填充,给出全黑);空批次不再 max(dim=0) 抛错。📌 刻意不改:match_size 会把小遮罩连同纵横比一起拉到对方的框(512x512 配 1024x256 变成 512x512,圆变椭圆)—— 那是这个选项的代价不是疏漏,要保比例得先各自缩放 |
| QG_TextSplit | 文本按分隔符分割 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「TextSplitByDelimiterEnhanced」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):三路输出(ALL / LIST / SEGMENT)、四个序号、空段丢弃、默认 <think> 全不变,老存档照开。🔴 修掉一个真假判:SEGMENT 的取数池写成 total if input_source == "文本框" else selected_pieces,而这个输入的值从 v0.8.5 起就是 text-field / external-list,条件永假 → 永远读 selected_pieces。文本框模式下两者同源所以看不出来,唯独 list_index=0(LIST 被清空)时 SEGMENT 跟着一起空掉 —— 而它只该受 segment_index 支配(实测:segment_index=2 + list_index=0,修前 "",修后 "b")。现在按常量 TEXT_FIELD 比。另外两处:① 非法正则分隔符原来抛裸英文 missing ), unterminated subpattern,改成中文点名「分隔符」并提示可以关掉「用正则」;② FUNCTION 改 execute 统一命名(存档不存方法名)。📌 保留一个已知行为不改:正则模式用捕获组时分隔符会留在结果里(re.split("(,)", "a,b") → ['a', ',', 'b']),那是 Python 的语义、偶尔正是想要的,只在文档里写明 |
| QG_SizeSelector | 尺寸选择器 | 原创 | 本插件自己写(参考 ComfyUI_Muye(MIT)「MuyeSizeSelector」的用法,代码重写);v0.8.5 搬入,v0.9.4 起多次重写,10-30 收口为自写实现 |
| QG_EmptyLatentResolution | 空 Latent 分辨率 | 原创 | 本插件自己写(作者自有旧插件 ComfyUI-EmptyLatentResolution(MIT)「EmptyLatentResolution」合并进来);把官方 ResolutionSelector(比例 + 百万像素 → 宽高)与 EmptyLatentImage(宽高 + 批量 → LATENT)合成一个节点,省掉中间两根线。尺寸算法与 ResolutionSelector 逐行一致(同样的 sqrt 缩放与 multiple 取整,128 组参数实测逐个相同),latent 结构与 EmptyLatentImage 一致(4 通道、intermediate_device / intermediate_dtype、downscale_ratio_spacial=8);另给 RESOLUTION_PREVIEW 预览控件(optional,三个 _widget 指向真实输入) |
| QG_TextConcat | 文本合并 | 原创 | 本插件自己写(参考 ComfyUI_Comfyroll_CustomNodes(MIT)「CR_TextConcatenate」的用法,代码重写);自写(10-30 换掉 v0.9.4 的搬运版):ID / 输入名 / 槽名 / 分隔符是控件 / 不做 trim,全不变,老工作流照开。真改进是分得开「没接线」和「接了但是空」—— 搬运版两路默认都是 "",于是判不出某一路是不是根本没接,分隔符照样吐:只接文本1 得 "A-"、只接文本2 得 "-B"、两路都不接得一个孤零零的 "-"。现在没接的那一路用 _MISSING 哨兵认出来,连同分隔符一起省掉;接了线但是空字符串仍算参与(空 + "-" + X 还是 "-X")。🔴 判据依赖函数签名默认值是哨兵 —— ComfyUI 的 get_input_data 只返回 prompt 里真有的输入,没出现的交给 Python 用签名默认值补;哪天改成拿 INPUT_TYPES 的 default 填,这个区分会静默失效,_check_text_concat.py 里那条断言就是盯这个的。输出类型同时从 * 改成 STRING(原来名字写 STRING、类型是任意,自相矛盾) |
| QG_TextReplace | 文本替换 | 原创 | 本插件自己写(参考 ComfyUI_Comfyroll_CustomNodes(MIT)「CR_TextReplace」的用法,代码重写);自写(10-30 换掉 v0.9.4 的 Comfyroll 搬运版;更早的 v0.8.5 ~ v0.9.3 搬的是 Muye BatchTextReplace,两份旧存档都由 web/text_replace/ 自动迁移)。ID / 文本槽 / 六组查找替换 / 三条规则按序 / 空查找跳过 / 不做 trim 全不变。保留了我们自己加的两处:mode(literal 默认,字面量下括号点号竖线都是普通字符)与空查找跳过(str.replace("", x) 会在每个字之间插替换串)。这次修的三处 —— ① RETURN_TYPES 是 * 而 RETURN_NAMES 写 STRING,自相矛盾,改真类型 STRING、槽名 text;② FUNCTION 改 execute 统一命名(存档不存方法名,前端 web/text_replace/ 只按 widget 位置迁移,不受影响);③ 🔴 regex 模式只 catch 了 compile 阶段的错,sub 阶段的错会漏出原始英文 —— 而 sub 阶段最常见的正是替换内容里的反斜杠:Python 的 re.sub 把替换文本当模板,C:\temp 会静默变成「C: + 制表符 + emp」( 是合法转义,拦不住,只能文档说明),C:\xyz 直接抛 bad escape \x。现在两个阶段都 catch,错误用中文点名「第几条规则」+「查找内容还是替换内容」+「反斜杠要写两次」。🔴 前端迁移依赖 widgets_values 的长度是 7(text 是 forceInput 不产生 widget),改输入数量会整排错位 |
| QG_ColorCorrect | 颜色校正 | 原创 | 本插件自己写(参考 comfyui-art-venture(MIT)「ColorCorrect」的用法,代码重写);只沿用六个滑条的参数划分与作用顺序(色温/色调/明度/对比度/饱和度/伽马),实现整段自己写:纯 torch、全 float、不依赖 cv2,并修掉参考实现的三处问题(逐帧 8bit 往返导致色阶、饱和度实际改的是 HLS 明度通道、色温乘单通道会连带变亮) |
| QG_ColorMatch | 颜色匹配 | 原创 | 本插件自己写;十种方法都是公开算法的自写实现,代码未搬任何插件:Haar 小波 3 层只匹配低频子带、AdaIN 逐通道实例归一化(sRGB 上、单尺度)、RBF 核 MMD 拟合仿射映射、逐通道 CDF 分位匹配、Reinhard LAB 逐通道均值/标准差(2001)、LAB 3x3 协方差匹配(Pitié 2007 线性 MKL 的核心:白化再着色)、两种三步串联(直方图-多元高斯-直方图、直方图-MMD-直方图)、Reinhard 的整批 4D 实现、仅匹配均值;训练无关、纯 torch,出口走 LCh 保色相缩 chroma 而非逐通道硬裁;遮罩 / 羽化 / 强度 / 匹配范围 / 参考取帧 / 目标统计 / 遮罩用途 / 参考遮罩 / 细节回填是本插件自己的参数划分 |
| QG_ImageResize | 图像缩放 | 原创 | 本插件自己写(参考 rgthree-comfy(MIT)「RgthreeImageResize」的用法,代码重写);自写(10-30 换掉 v0.8.0 的搬运版):ID / 六个控件的顺序 / 三路输出都不变,仍走核心 common_upscale。修掉三处 —— percentage 下 1% 的窄图换算后是 0 像素,与「没填」的哨兵撞车,原版会把 1% 读成整宽;1000x1 这种图按宽推高算出 0,common_upscale 直接抛;无操作分支原版返回输入张量本身(其余分支返回新张量),输出是否与上游共 storage 取决于走哪条分支 |
| QG_ImageOrLatentSize | 图像或 Latent 尺寸 | 原创 | 本插件自己写(参考 rgthree-comfy(MIT)「Image or Latent Size」的用法,代码重写);自写(10-30 换掉搬运版):ID / 通配输入 / 两路 INT / WIDTH·HEIGHT 槽名全不变。🔴 修掉的核心缺陷:只认四维张量,而 ComfyUI 的 MASK 主流是三维 —— ImageToMask 给 image[:,:,:,channel]、LoadImage 给 mask.unsqueeze(0),都是 (B,H,W)。旧版 if len(shp)==4 之外一律 return (0,0),于是接最常见的遮罩得到 0×0,且没有任何提示(真机:同一张图 IMAGE 读 2560×3413、MASK 读 0×0)。现在 2/3/4 维都认:三维 (B,H,W)、二维 (H,W)、四维 (B,1,H,W)。🔴 四维歧义((B,H,W,C) 与 (B,1,H,W) 都是四维)不能只看第二维 —— 高度为 1 的图会被当成遮罩;判据改成「第二维为 1 且 末维不是通道数(1/3/4)才算遮罩」。另修一处:通配 * 输入漏了 forceInput,前端会在画布上多画一个填了也没用的文本框(QG_Exists / QG_RouteBlocker 同款)。LATENT 取最后两维(支持五维视频 latent)×8。断言 tools/_check_image_or_latent_size.py(29 项)+ 真机 _check_image_or_latent_size_live.py(12 项) |
| QG_GoogleTranslateText | Google Translate | 原创 | 本插件自己写(参考 ComfyUI_Custom_Nodes_AlekPet(MIT)「GoogleTranslateTextNode」的用法,代码重写);上游依赖 googletrans(驱动未公开的 Google 网页端点,隔几个月坏一次);这里直接用 requests 打同一批端点,代码里没有一行上游实现 |
| QG_AnySwitch | 任意切换 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiAnySwitch」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):ID / 16 个槽名 / 输出名 / 分类 / * 通配类型全不变,槽序仍只认数字后缀(前端会把槽名改成「图像_1」这种可读文字,按名字认槽会乱序丢线)。修掉三处 —— ① 音频 {waveform} 和任意字典同算 dict,混接被放行(真机复现:音频配一路杂字典,原版原样输出);② 报错只列类型不列槽,IMAGE, LATENT 得自己数到第几路,现在写 any_02 是 LATENT;③ 「一路没接」与「接了但值全空」都报「所有输入均为空」,可两者修法完全不同(去接线 / 查上游为什么吐空),现在分开报。另修:AnyType 覆盖 eq 却没给回 hash,Python 会把 hash 置空让实例不可哈希(实测 TypeError,任何 {类型: …} 或 set() 都会炸),通配类型已抽到 nodes/_qg_any_type.py 复用。📌 刻意不做懒执行:判空必须先求值,输入一懒就变成逐路索要 + 反复重调度;真要省掉整条分支的计算,If / Else 才合适 |
| QG_DisplayAny | 展示任意 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiDisplayAny」的用法,代码重写);自写(10-30 换掉 v0.8.5 的搬运版):ID / 槽名 Any / 输出名 Any / OUTPUT_NODE / ui 键 qg_display 及其 type/size/text/images/audio/video 字段全不变。修掉四处 —— ① 四维遮罩预览不了:官方写明 MASK 是 [H,W] 或 [B,C,H,W],原版只认前两种,拿到 [B,1,H,W] 直接抛「遮罩应为 [B,H,W] 或 [H,W]」,界面上只看到「预览失败」;② 没接线时显示字符串 "None"(describe(None) 的返回值),现在发 notice 代码让前端出提示;③ 后端把「预览失败」「该视频格式不支持」两句中文拼进 text,英文界面也是中文,现在后端只说代码、文案在前端 zhPair;④ prompt 钩子会把唯一目标也摘掉 —— 「只执行选中的节点」选中展示节点时 targets 只有它,摘完变成空列表,核心 validate_prompt 判 Prompt has no outputs 直接拒单(真机复现);现在摘完为空就不摘。另修:顶层超长文本原样全推(10MB 就整段走 WebSocket 再进 DOM),现封顶 100000 字符并给 notice;AnyType 覆盖 eq 未给 hash(见 _qg_any_type.py);PromptServer.instance 是实例属性、无服务器时直接访问是 AttributeError 不是 None,原版那句会让整包 import 失败。前端面板另把 20 处硬编码中文改成 zhPair(槽位类型名 / 文本字号 / 复制保存提示 / 画册按钮 / 右键菜单),并新增 notice 渲染。📌 保留:预览失败绝不阻断数据流、out 与 in 是同一个对象 |
| QG_RouteBlocker | 路由阻断 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiRouteBlocker」的用法,代码重写);自写(10-30 换掉 v0.8.0 的搬运版):ID / 槽名 / 选项值 / 三种结果全不变,老工作流照开。真改进是给 any 加 lazy —— 搬运版先求值上游再判断,开关打开时整条上游照样跑完(贵采样器白跑一遍)才把结果丢掉;现在开关打开时上游一个节点都不排队。any 没接线用 _MISSING 哨兵区分,lazy 输入下 None 表示「接了还没求值」,混用会让没接的线一直空等 |
| QG_IfElse | 是否判断 | 原创 | 本插件自己写(参考 ComfyUI-Easy-Use(GPL-3.0)「easy ifElse」的用法,代码重写);自写(10-30 换掉 v0.8.0 的搬运版):ID / 槽名 / 懒执行都不变,老工作流照开。两路改成 optional + lazy,只接一路也成立(那一路总被选中),读法与核心 ComfySwitchNode 一致;两路全空在 VALIDATE_INPUTS 拦,否则懒状态会一直索要一个不存在的输入 |
| QG_MDReader | 加载文档 | 原创 | 本插件自己写(作者自有旧插件 ComfyUI-MD-Reader(MIT)「MarkdownFileReader」合并进来);扫 input(4 层)与旁边 md / markdown / prompts / prompt 目录;节点内带预览、放大窗与一键复制 |
| QG_TripleLoader | 模型加载器 | 原创 | 本插件自己写(作者自有旧插件 ComfyUI-TripleLoader(MIT)「TripleLoader」合并进来);import 期就实例化内置 UNET / CLIP / VAE Loader |
| QG_StringSwitch | 字符串切换 | 原创 | 本插件自己写(参考 ComfyUI-Crystools(GPL-3.0)「Switch string [Crystools]」的用法,代码重写);只借「两个分支是可编辑框而不是槽」这个思路,文案也全部重写 |
| QG_BoolToggle | 布尔开关 | 原创 | 本插件自己写;交互参考孤海「布尔」,卡片绘制 / 等比缩放 / 命中区是自己写的 |
| QG_Number | 数值 | 原创 | 本插件自己写;整数 / 浮点合一 |
| QG_Slider | 数值滑条 | 原创 | 本插件自己写;一行:滑条 + 读数 + 齿轮;范围 / 步长 / 类型收在齿轮菜单里 |
| QG_Math | 数学运算 | 原创 | 本插件自己写;一行表达式,白名单求值 |
| QG_Exists | 存在判断 | 原创 | 本插件自己写;判定口径与孤海「万能是否存在(GH)」对齐(全黑 MASK / 全零 LATENT 算没有),代码自写且只判不改 |
| QG_CanvasLabel | 画布标签 | 原创 | 本插件自己写;纯前端裸节点,无输出,不进 prompt |
| QG_MarkdownNote | Markdown 便签 | 原创 | 本插件自己写;纯前端裸节点,自带 Markdown 渲染(web/shared/md_render.mjs) |
| QG_ExportImage | 导出图像 | 原创 | 本插件自己写;只借了 KOOK / 孤海同类节点「quality 该放在哪」的结论 |
| QG_LoadImage | 加载图像 | 原创 | 本插件自己写(参考 Goohaitools-comfyui(GPL-3.0)「加载图像」的用法,代码重写);契约照孤海那支定:两个输出(图像 / 遮罩)、一个「保留透明通道」开关、编辑器存「原图副本 + alpha 带遮罩的成品」两个文件、读回时用副本的 alpha 换掉成品的 alpha,所以遮罩默认不进画面。带色图做成可选开关(孤海是二选一的档位),颜色与浓度直接吃编辑器里的九色板和透明度滑块,存盘时回写到这两个控件。实现自写:配对靠文件名里的 13 位时间戳(孤海靠像素比对 + 修改时间反查),只写两个文件,读写复用 _qg_media_helpers |
| QG_StepPreview | 采样预览 | 原创 | 本插件自己写;自写。只用 ComfyUI 官方机制,没有搬任何插件的代码:开关靠 PromptServer.add_on_prompt_handler 在排队前改写 extra_data["preview_method"](PromptExecutor.execute_async 会读它),预览尺寸改 latent_preview.MAX_PREVIEW_RESOLUTION,老版本没有 override 时退化成直接改 cli_args.args.preview_method。前端面板自写(web/step_preview/index.js):监听 b_preview 事件把帧画进节点,带步骤计数与 STOP(调 api.interrupt),面板结构与高度自适应复用本插件自己的 panel_layout,未用任何上游代码 |
| QG_MaskCrop | 遮罩裁剪 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GH_MaskCropV2」的用法,代码重写);自写。功能对位孤海「遮罩裁剪V2」,代码一行没抄:几何全在 nodes/_qg_mask_crop_helpers.py 的纯函数里(plan_crop 负责四方向按最短边倍数扩展、native / square / custom 三种取景、multiple 向上取整),不依赖 PIL / cv2 / scipy;越界部分按方向取边缘众数色或边缘拉伸填充(孤海是 PIL putpixel 逐像素写);custom 用 cover 语义先扩矩形再 resize,不会像 fit 那样把主体压窄;整批共用并集包围盒,视频帧不抖 |
| QG_CropRestore | 裁剪恢复 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GH_CropRestore」的用法,代码重写);自写。功能对位孤海「裁剪恢复」,代码重写:像素级 expand / feather 取代百分比;只写落在画面内的部分,遮罩外像素与原件逐像素相同(同尺寸回贴实测差 0);另加可选的整体中位配色对齐,孤海那套排除重绘区的加权最小二乘没有照搬 |
| QG_MaskAlign | 遮罩对齐 | 原创 | 本插件自己写(参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「孤海-遮罩对齐」的用法,代码重写);自写。功能对位孤海「遮罩对齐v2」,代码重写:两个轴各给四个锚点(center / left / right / top / bottom / none),不是开关二选一;搬移保留原始软边,不重画成矩形;整批只算一个偏移(包围盒取并集),视频帧不漂;aligned 与 bbox 拆成两个输出,union_bbox 才与参考取并集 |
| QG_CropForInpaint | 重绘裁剪 | 原创 | 本插件自己写(参考 ComfyUI-AusBoss(MIT)「Crop For Inpaint 🆎」的用法,代码重写);自写。参数与上游逐项一致、范围默认值都对齐(tools/_check_stitch_inpaint.py 的 A 组断言),因为缝合数据是跨插件契约:同一个 stitcher 必须能被两边的 Stitch Inpaint 读出同样结果。算法不另写,直接用 v0.5.0 随「裁剪+旋转+补边」搬进来的 _qg_inpaint_crop_helpers.build_crop;节点层只做三件事——把 18 个控件原样转进去、接住空遮罩、在开头结尾查中断。比上游多一步:核心加载图像没画遮罩时给的 64×64 全零占位先换成同尺寸零遮罩,让它走「选整图、原样贴回」那条分支,而不是被判尺寸不符整条 prompt 崩掉(10-29 在遮罩裁剪上踩过同一个坑) |
| QG_StitchInpaint | 重绘缝合 | 原创 | 本插件自己写(参考 ComfyUI-AusBoss(MIT)「Stitch Inpaint 🆎」的用法,代码重写);自写。上游整个 stitch() 就是 apply_stitch + stitch_blend_mask 两行,算法同样直接用搬进来的 helper,节点层只补输入校验和老存档容错:seam 为空串/None 时按 classic 走(VALIDATE_INPUTS 也要放行,否则老工作流排不进队列)。输出与上游逐像素一致(含 color_match、fix_edge_halo、seam=blend in 对 Crop 缝合数据降级这三种组合),四种交叉接线也一一验过:AusBoss 的 stitcher 喂本节点、本节点的 stitcher 喂 AusBoss 节点,结果全等 |
| QG_FreeMemory | Free Memory | 搬运 | ComfyUI-AusBoss(MIT)「Free Memory 🆎」 |
| QG_LoraLoader | LoRA Loader | 搬运 | ComfyUI-AusBoss(MIT)「LoRA Loader 🆎」 |
| QG_WorkflowNote | Workflow Note | 搬运 | ComfyUI-AusBoss(MIT)「Workflow Note 🆎」 |
| QG_WorkflowSwitches | Workflow Switches | 搬运 | ComfyUI-AusBoss(MIT)「Workflow Switches 🆎」 |
| QG_ImageCompare | 图像对比 | 搬运 | ComfyUI-AusBoss(MIT)「Image Compare A/B 🆎」 |
| QG_Seed | 种子 | 搬运 | ComfyUI-AusBoss + rgthree-comfy(MIT)「Seed 🆎 / Seed」 |
Load Image(加载图像)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_LoadImage)· 参考 Goohaitools-comfyui(GPL-3.0)「加载图像」的用法,代码自写
官方的 Load Image 有两处让人默默吃亏:透明 PNG 被压成三通道,透明处的原始颜色 (多半是黑)会跟着进下游,抠图一合成就是一圈脏边;没有 alpha 的文件则退回一块 64 × 64 的遮罩,跟图片尺寸毫无关系。
透明只由一个开关管:
| 保留透明通道 | 图像输出 | |---|---| | 关(默认) | 透明处合成白底,跟看图软件看到的一样,三通道 | | 开 | 原样输出四通道 RGBA |
遮罩输出尺寸恒等于图片,画上的地方为 1、没画的地方为 0,可以直接接局部重绘。 输出只有这两个;宽、高、帧数写在面板图下方,不占输出槽(早先还有个「文件名」槽, 用来给导出节点起名 —— 那件事一个字符串节点就能做,占一根线不值)。
想在一张图上直接看到遮罩范围,打开输出带色图:把编辑器里画好的颜色一起带出来 ——
每一笔保留自己选的颜色(红一笔、蓝一笔都行),浓度就是编辑器里那根透明度滑条。
默认关 —— 关着 IMAGE 是干净的原图。颜色烧在成品 PNG 的 RGB 里,而干净画面是从配对的原图
副本取的,所以怎么画都不会把颜色漏到干净输出上。
| 输入 | 说明 |
|---|---|
| image | input 里的图片;上传、拖拽、选择器都落到这里 |
| 保留透明通道 | 关:透明处合成白底,三通道;开:原样四通道 |
| 输出带色图 | 由编辑器顶栏那三段决定(不是面板上的开关了):彩色叠加带色,另两个只存遮罩 |
| upload | 上传按钮,只藏外观不动 widget 顺序 |
面板上只留四样:文件名 + 上传、图、编辑遮罩、宽 × 高 + 一颗齿轮。齿轮里只剩
「保留透明通道」(跟输出格式有关,不属于画遮罩那套)。点面板外面、滚一下画布、按 Esc 都会收起。
「带不带色」是画的时候在编辑器里定的(照孤海的做法):顶栏三段「彩色叠加 / 仅遮罩 / 原图」 决定存出去的成品 —— 只有彩色叠加把颜色烧进 RGB,另两个只存遮罩。屏幕上除了「原图」那一档, 看到的永远是带色的图,所以「仅遮罩」不会让你眼前一黑。颜色点哪一颗、浓度拖多少也都在编辑器 底栏里定,保存时连同输出档位一起回写节点。
遮罩编辑器画的结果默认不会进画面。 这一点照孤海那支的做法:保存时在 input/clipspace
下同时写三个 PNG —— 一份原图副本(留住它自己的 alpha),一份不透明的带色画面(给编辑器
取颜色用),一份把遮罩存进 alpha 通道的成品;读回来时用副本的 alpha 换回成品里的 alpha,所以 IMAGE 是画之前那张图,
遮罩只走 MASK。孤海把「带不带色」做成两个互斥的档位,这里只有一个开关:默认关,
开着才按编辑器里选的颜色和浓度刷进 IMAGE。两边都能要到同一张带色图,区别只是
默认值站在「干净」这一边。
孔洞填充在编辑器里,而且是自动的(孤海那支一样自动:勾上它的「填充孔洞」,抬笔后
自己在 setTimeout 里重算填充层,不用点按钮)。我们默认开着、每次抬笔补一遍。
落笔过程中看到的是笔迹本身,不是填充层 —— 孤海也是这么分的:画的时候用
drawingPreviewPaint(原始笔画),pointerup 之后才换成 filledPaint。所以洞里补上的
那一下会跳一格,那是抬笔后才有的动作。
它只补「被遮罩围死的洞」:灌水用 alpha > 5 当墙(跟孤海一字不差)、灌水本身不膨胀,所以
外缘不会越补越胖。墙的门槛别再往高里调 —— 用 128 的话,软边笔画围出来的圈会被边缘那圈
半透明当成「没画」,灌水顺着边上漏出去(实测 100% 软度 200px 笔宽的圈:> 5 补 41418 px,
>= 128 只补 13326 px)。早先是先膨胀 2 像素再灌水,好处是收笔时那条 1px 的缝也能补上,
代价是每抬一次笔遮罩就胖一圈;自动模式每次抬笔都跑,这个代价付不起,宁可少填。
填充只是看得见的一层:它每次都从原始笔画重算,不算笔画,撤销回退的是笔本身,
关掉开关立刻回到手画的样子。
不过算完洞之后会把洞往笔迹里多吃 3 像素(growIntoWall)。洞和笔迹的交界本来是
「实心 255 紧贴着抗锯齿的 alpha≈6」,中间夹一圈淡沟;在 50% 预览下、尤其白底图上,
那圈就是一道像虚线的浅痕。孤海没这个问题,是因为它把墙一起涂成实色(rebuildSingleColorFill
里除了「墙外的空白」全是 255),代价是笔迹边缘也变硬。我们只在洞这一侧补实,笔迹外缘
的软边照旧留着。多吃的那 3 像素只往「已经有颜色」的像素里长,不会推到空白处把遮罩撑胖。
笔尖圈是深色垫底 + 白色细线两道描边:只描白线的话,白底图上整个圈看不见。
填充按颜色分开存,各跟各的笔画(fillLayers)。以前是「所有颜色的洞合成一张、盖在所有笔画
最上面」,于是先画的红色圈填满之后,再换绿笔在红块上画,绿笔会被红洞整块盖掉。现在每色的洞跟
自己的色层一组,组与组之间按这一色最后落笔的先后排 —— 后画的那一组整体在上面:
| 你画的顺序 | 结果 | |---|---| | 先红圈 + 填满,后画绿笔 | 绿组最后落笔,绿笔压在红洞上,看得见 | | 先绿块 + 填满,后画红圈 | 红组最后落笔,红洞连绿一起盖住,圈里整个变红 |
洞只补「原本没遮住」的地方:打开一张成品时那 9 个色层是按颜色拆开的碎片,对碎片灌水会把 碎片之间的小缝当洞,实测一张成品重开一次就能多出 5 万多像素的假洞、颜色越存越白。已经有遮罩的 区域一个像素都不碰,反复存盘的颜色也就稳了(实测四次存盘逐像素一致)。
面板怎么用
| 操作 | 效果 | |---|---| | 点选择器 | 列出 input 里的图片,指针划过就在右边预览 | | 上传 / 把文件拖到节点上 | 传进 ComfyUI 的 input 文件夹并选中 | | 右键 → 在遮罩编辑器中打开 | 用官方遮罩编辑器涂抹,保存的结果写回同一个控件 | | 点「保留透明通道」胶囊 | 切换四通道 / 白底合成 | | 点「编辑遮罩」/ 双击图 | 打开遮罩编辑器,直接在这张图上画遮罩 | | 拖节点左右边缘 | 预览跟着变宽;高度是常数 200px,不跟图片走 |
面板上那层绿只是「遮罩范围」的提示,跟输出的颜色无关;要换输出的颜色和浓度,用右侧的
遮罩颜色 / 遮罩透明度,或者直接在编辑器里选(存盘时回写到这两个控件)。
编辑器里的色点就是笔色:点红画红、点蓝画蓝,成品里一笔一色。
遮罩编辑器
点「编辑遮罩」(或者双击图)就打开一个全屏编辑器:画笔、橡皮、笔宽 / 软度 / 透明度三根滑条、
撤销重做、清空、反色、自动填充漏洞、九色板(它同时是笔色)都有,笔的用法和图像对比的橡皮擦是一套
([ ] 改笔宽、Shift 加 [ ] 改软度、按住 Alt 加右键拖着调、右键或 Ctrl
反过来用当前的笔)。软度默认 0(硬笔):抠头发丝、衣领这种地方硬边更好对,想糊开自己往上调。
滚轮缩放画面,按住空格或中键拖动平移(跟孤海一样:滚轮以指针为锚点,0.05 ~ 12 倍)。 缩放只改画面的 CSS transform,遮罩位图一个像素都不重算,所以放大后照样流畅;笔迹仍然落在 指针底下,越放大越好抠细节。
| 显示模式 | 看到什么 | |---|---| | 显示:彩色叠加(默认) | 遮罩区域盖一层当前颜色,浓度就是底栏那根透明度滑条 | | 显示:仅遮罩 | 底图压暗,遮罩区域纯白 | | 显示:原图 | 不画遮罩,方便对位置 |
存盘写两个文件到 input/clipspace/,原图不动。 官方的遮罩编辑器是把遮罩烧回
原图、覆盖 input 里那张文件(文件名末尾的 [input] 只是路径提示,不是文件名的一部分),
画错一次原图就没了;这里原图永远在,想重来就回到原图再画一次。
| 文件 | 内容 |
|---|---|
| qg-src-<时间戳>.png | 原图副本,只为了留住它自己的 alpha |
| qg-painted-<原名>-<时间戳>.png | 成品:RGB 是画面,alpha 是遮罩 |
两个文件用同一个 13 位时间戳配对(qg_load_image.py 里的 PAINTED_NAME)。读的时候
成品里的 alpha 被副本的 alpha 换掉,所以 IMAGE 是画之前那张图,遮罩只出现在 MASK 上。
成品名里带着原文件名,只是方便人认,不再单开输出槽。
节点里的预览和编辑器里的底图看的是副本,不是成品。 成品那张图的 alpha 就是遮罩, 浏览器一渲染遮罩区域就成了透明 —— 所以凡是「要看画面」的地方一律拿副本,遮罩另从 成品的 alpha 里读回来。二次编辑就是这样接着上次的遮罩改的。
遮罩范围在预览里显示成一层固定的半透明绿(42, 210, 112 @ 50%,只是提示层,
不跟输出的颜色走),只画在节点面板的那张 canvas 上,源文件一个字节都不动。这一层和原图
是上下两层叠在一起的:原图照常显示,上面那张 canvas 只画刷过的地方,其余透明。
不做 PNG 编码 —— 早先的版本把两层合成为一整张图再 toBlob,1 兆像素的图光编码就
1.1 秒(热态也要 90ms),而那张图只是为了让浏览器马上再解码回来显示。官方核心的遮罩
编辑器也是这个路子:遮罩是独立一层 canvas,靠 opacity / mixBlendMode 叠在画面上,
改颜色只写 RGB 三个字节。
同一套做法孤海也在用(它是
painted-*三个文件);区别是我们只写两个,而且原图 副本只被读 alpha,不参与输出。它的绿色预览是另一个做法:三层<img>叠着,绿层直接 复用原图 URL 加一串 CSSfilter染色,靠最上层那张「挖过洞的图」当遮罩。
预览的高度是常数 200px,跟图片多大、多长都没关系 —— 选一张 2560 × 3413 的竖图,
节点也不会被撑成一根细高条。图片在自己那块框里等比缩到装得下(object-fit: contain),
不裁切、也不回头改节点尺寸。想看仔细就双击进遮罩编辑器,那儿是全屏的。
两种画布都是同一块面板:经典画布和 Nodes 2.0 都能用。
输入 / 输出
| 输出 | 说明 |
|---|---|
| IMAGE | 图片本体。默认是画之前那张图(遮罩不进画面);开了「输出带色图」则把编辑器里的多色带出来。关掉「保留透明通道」时是三通道 |
| MASK | 画上的地方 1、没画的地方 0;尺寸恒等于图片 |
只有这两个。宽、高、帧数本来就写在面板图下方(1036 × 584),文件名用字符串节点就能
拿到 —— 把它们做成输出槽,只是让人在画布上多接几根线。
Image Crop + Rotate + Pad(裁剪 + 旋转 + 补边)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ImageCropRotatePad)· 参考 ComfyUI-AusBoss(MIT)「Image Crop + Rotate + Pad 🆎」的用法,代码自写
载入一张图,在节点上的编辑面板里做一次旋转 / 裁切 / 补边,输出摆正并补好画布的画面, 外加一份标出「该生成哪里」的遮罩。
面板怎么用
| 操作 | 效果 |
|---|---|
| 拖画面 | 平移取景框里的画面 |
| 拖角 / 拖边 | 改裁切框 |
| 旋转 | 顺时针旋转(rotation_degrees,-180 ~ 180) |
| 拖画布边 | 给某一边补出 fill_color 的边(拖出来的就是 padding) |
| 比例 | crop_aspect_ratio:锁定裁切框比例,free 任意、source 跟随原图 |
面板上的改动会直接写回节点参数,所以保存、撤销、API 调用都走 ComfyUI 原生路径。
遮罩里有什么
mask 白的地方就是「可以让模型画」的地方:
- 补出来的边(padding);
- 旋转留下的空角;
- 原图里透过去的地方(实心度不足 90% 的像素,比如抠图留下的透明边)。
不想让透明区域被当成待生成区域,把 painted_area 设成 keep picture —— 底下原样保留,
只靠遮罩标记。
缝合器
stitcher 是一份「怎么把生成结果贴回原图」的说明,接到下游的缝合节点
(AusBoss 的 Stitch Inpaint,或本插件将来搬过来的同类节点)就能自动对齐贴回。
stitch_blend 控制贴回的过渡带宽度,stitch_grow 控制贴回边界往哪偏。
出规则尺寸
canvas_multiple(Divisible by)把输出长宽凑成它的整数倍:有补边的那一侧多补几个像素,
没补边的那一侧就裁掉几个像素(两侧各裁一半)。要 8/16/32 整除的模型设这里,1 = 关闭。
resize_to_megapixels + megapixels 可以再把结果缩到指定像素预算(与核心
Scale Image to Total Pixels 同语义)。
输入 / 输出
14 个必填 + 7 个可选,全部是画布上的参数;画面上常用的一些 (比如旋转、裁切、补边)藏在面板里,不会挤满节点。
| 输出 | 说明 |
|---|---|
| image | 变换后的图像 |
| mask | 待生成区域(补边 / 旋转空角 / 透明处) |
| stitcher | 缝合器(贴回原图用) |
| original | 变换前的原图 |
| width / height | 输出尺寸 |
| prompt_image | 给模型看的提示图(带待生成区域的示意) |
自定义比例预设(可选)
把插件根目录的 qg_presets_example.json 复制成 qg_presets.json 再改,
可以往比例下拉里加自己的 W:H 条目。文件里有坏条目只会警告一次并跳过,不影响节点注册。
LoRA Loader
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_LoraLoader)· ComfyUI-AusBoss(MIT)「LoRA Loader 🆎」,只改类名 / 分类 / 显示名 / 中文文案
一个节点管整摞 LoRA:接上 MODEL(可选接 CLIP),下面排开你要用的所有 LoRA,
输出打好补丁的模型和一行触发词。
每一行有什么
| 控件 | 作用 | |---|---| | 拖拽手柄 | 按住上下拖动,调整 LoRA 的应用顺序 | | 开关 | 临时旁通这一行,不必删掉它 | | 名字 / 选择器 | 点一下打开搜索框挑文件;名字太长会按设置省略 | | 强度 | 直接在名字上左右拖动就能调,也可以点进数值框;旁边有中心零点强度条 | | ⓘ | 悬停看预览图、底模、触发词,可顺手查 Civitai |
触发词
每个 LoRA 的触发词会自动汇总,去重后按 trigger_separator(默认 , )拼成一路 triggers
输出,直接接进提示词。也可以给任意一行手填自己的触发词。
有两个刻意的设计:
- 把某行强度调到 0,它的触发词仍然保留 —— 这样对比「用 / 不用这个 LoRA」时只需改权重,提示词不用动。
- 因文件缺失被跳过的那一行,不加任何词。
整摞存成模板
强度条那一排的 ▤ 按钮可以把当前整摞 LoRA 存成命名模板(存在浏览器本地)。 之后在任何 LoRA Loader 上点开 ▤ 就能一键套用,也能删除。
吸收模型链上的 LoRA
齿轮菜单里的 Absorb chain LoRAs 会沿本节点的模型链往上下游走,把路上遇到的其它 LoRA 加载器 (包含 rgthree、JPS、Pixaroma 等插件的节点)的 LoRA 全部并进本节点,再把那些节点自动旁通 —— 出图结果完全不变,只是整摞 LoRA 集中到了一处管理。
前提是那些节点的 LoRA 不是从连线动态接进来的(例如 rgthree 的 Power Lora Loader 接了外部输入); 这种情况菜单会提示你先断开。整摞 LoRA 也有行数上限,超出时会提示你先清理几行。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必填) | model | 要打 LoRA 补丁的扩散模型 |
| 输入(必填) | loras | 序列化的 LoRA 栈,由面板托管 —— 改行,不要改这个值 |
| 输入(可选) | clip | 不接的话 CLIP 强度会被忽略 |
| 输入(可选) | trigger_separator | 触发词之间的分隔符,默认 , ;在齿轮菜单里改,画布上隐藏 |
| 输入(可选) | on_missing | 文件缺失时怎么办,见下 |
| 输出 | model | 按行顺序打完所有启用 LoRA 的模型 |
| 输出 | clip | 同样处理过的 CLIP |
| 输出 | triggers | 所有启用行的触发词,去重后拼成的一行字符串 |
文件找不到时
- LoRA 只是被移动过(还在
loras目录里、换了子文件夹)会在运行时按文件名自动找回来,不用管。 - 真的找不到时,默认行为是在采样前直接报错停下,并在错误信息里点名是哪个文件 —— 无人值守或脚本化跑图不会静默地少打一个 LoRA。
- 想让它在控制台警告一声然后跳过这一行,把齿轮菜单里的 Stop on missing LoRA 关掉即可
(API 调用时对应
on_missing: "skip")。
设置
齿轮按钮里是这个节点类型的偏好设置,存在浏览器本地,跟着你所有工作流走:
| 设置 | 默认 | 作用 |
|---|---|---|
| Default strength | 1.0 | 新加一行时的初始强度 |
| Strength step | 0.05 | 拖动与方向键的步长(按住 Shift 恒为 0.01) |
| Separate model / CLIP strength | 关 | 每行显示两个强度框,分别控制模型和 CLIP |
| Strength bars | 开 | 名字后面的中心零点强度条(青色向右为正,红色向左为负) |
| Trigger word separator | , | 拼接 triggers 输出用的分隔符 |
| Stop on missing LoRA | 开 | 关掉后,文件缺失只警告并跳过 |
| Hide file extension | 开 | 名字不显示 .safetensors |
| Hide folder names | 开 | 只显示文件名(完整路径仍在提示里) |
| Civitai lookup button | 开 | 信息卡里提供「查 Civitai」按钮 |
| Long names | end | 名字太长时怎么省略;middle 会保留结尾的数字 |
| Scrub strength on the name | 开 | 在名字上左右拖动改强度(单击仍然是打开选择器) |
| Preview thumbnails | 开 | 悬停选择器时显示预览图 |
模型加载器(三合一加载器)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TripleLoader)· 作者自有旧插件 ComfyUI-TripleLoader(MIT)「TripleLoader」,合并进来
把 扩散模型 + 文本编码器 + VAE 三个加载器并成一个节点:三样各选一次,
输出标准 MODEL / CLIP / VAE 三路,接到采样器上即可。原本要摆三个节点、来回改三处下拉,
现在一块面板说完。
- 不绑模型家族 —— 底下跑的就是 ComfyUI 三个原生加载器,下拉里的文件列表、权重类型、 CLIP 类型、加载设备全部在启动时从本机现读,所以 Qwen-Image / Flux / SD 系列都照常能用; ComfyUI 升级后选项自动跟着变,不用等插件更新
- 下拉看全路径,节点上看短名 —— 下拉列表里显示完整路径便于区分同名文件; 选中之后节点上只留文件名,不会把节点撑宽(存的值仍是真实路径,不会被改写)
- 旧工作流不会断 —— 万一某行存的是裸文件名、或路径分隔符不一样,
运行时会按文件名在
models/下自动找回;真找不到才报错,并点名是哪个文件
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必填) | unet_name | UNET / 扩散模型 |
| 输入(必填) | weight_dtype | 权重精度,显存紧张可选 fp8_e4m3fn |
| 输入(必填) | clip_name | CLIP / 文本编码器 |
| 输入(必填) | clip_type | 文本编码器类型(Qwen-Image 选 qwen_image) |
| 输入(必填) | device | 文本编码器加载设备,选 cpu 可省显存(速度变慢) |
| 输入(必填) | vae_name | VAE |
| 输出 | MODEL / CLIP / VAE | 三路标准输出,直连采样器 |
Workflow Note(工作流说明卡)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_WorkflowNote)· ComfyUI-AusBoss(MIT)「Workflow Note 🆎」,只改类名 / 分类 / 显示名 / 中文文案
给别人(或者在半年后的自己)看的工作流说明书。节点本身不参与出图 —— 没有输入、没有输出、不进提示词, 就是画在画布上的一块卡片。
卡片上有什么
| 区块 | 内容 | |---|---| | 标题 / 副标题 / 作者 | 卡片抬头,纯文本,点铅笔进入编辑器改 | | 正文 | Markdown:标题、列表、代码块、链接都支持 | | Models | 工作流需要的模型:名称、目标文件夹、下载按钮 | | Node packs | 依赖的自定义节点包:包名、仓库地址、探测用的节点类 | | Links | 你自己的链接(GitHub、Civitai、教程……) |
自动对照本机安装
- 模型行:点
↻ check files会检查这个文件在对应的ComfyUI/models/<文件夹>里在不在。 - 节点包行:按「探测节点类」判断这个包在本机装了没有,装了就标
✓ 已安装,没有就标缺失并给「去获取」按钮。 - 文件在别处(比如放在别的子文件夹)也会指出来,甚至可以提示你哪个 LoRA 加载器的行需要指过去。
布局与数据
- 两种布局:卡片(默认,完整样式)和 横幅(只留一条标题标签)。
- 卡片内容存在节点的一个隐藏 STRING 字段里(JSON),所以保存、撤销、API 格式都走 ComfyUI 原生路径。
- 编辑器里有表单和「原始 JSON」两个页签,复制粘贴卡片给别人就靠 JSON 那页。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必填) | note | 卡片数据(JSON),由面板托管 —— 用卡片上的编辑器改,别直接改这个值 |
| 输出 | —— | 无。节点不会进入执行队列 |
Workflow Switches(工作流开关)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_WorkflowSwitches)· ComfyUI-AusBoss(MIT)「Workflow Switches 🆎」,只改类名 / 分类 / 显示名 / 中文文案
把一套工作流拆成几块,用一个节点统一切换。适合对比「开不开这一块」的效果、或者做「快速模式 / 全量模式」。 节点自身不运行,也不接任何线,纯粹是画布控制器。
建一个开关
- 在画布上选中一组节点(比如放大节点 + 它的保存节点)。
- 在开关卡片上点
+ Switch。 - 起个名字(比如「高清放大」)。
之后这个开关就是这一组的 关 | 开 按钮。关 默认是旁通(bypass)这些节点,图照常往下传; 在设置里可以改成静音(mute,下游拿不到输入会停下)。
三种不同粒度的开关
| 类型 | 建在哪 | 控制什么 | |---|---|---| | 节点开关 | 选中任意若干节点 | 这一组节点的开/关 | | 分组开关 | 选一个分组 | 整个分组的开/关 | | 全局开关 | 设置里的分组策略 | 按「不分组 / 每个分组 / 按编号分组」批量生成 |
打开「一次一个」后,打开某一行会自动关掉其它行 —— 适合「两个放大模型二选一」这类场景。
当参数预设用
开关不只管开关,也能改参数:选中节点后把当前值存成「开」的一套、改成另一套再存成「关」的一套。 之后一键就能把 Steps 设成 8、打开某个 LoRA 行,而不需要真的旁通任何节点。
输入 / 输出
| 方向 | 名称 | 说明 | |---|---|---| | 输入 | —— | 无 | | 输出 | —— | 无 |
开关状态存在节点自己的属性里,所以随工作流一起保存。
Run Timer(运行计时器)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_RunTimer)· 参考 ComfyUI-AusBoss(MIT)「Run Timer 🆎」的用法,代码自写
给整轮队列计时的一块读数面板。它不接任何线 —— 队列一开始跑就走字,跑完停住总时长, 纯粹靠监听队列状态工作。
| 行为 | 说明 | |---|---| | 计时 | 从队列开始执行起算,运行中实时走字,结束显示总时长 | | 历史 | 右键节点看最近几次的用时,改完设置好跟上一次比 | | 保存 | 时间随工作流一起存,别人打开你的图能看到作者那次的耗时 |
它不进提示词、没有输入输出,只影响画布上的显示。
输入 / 输出
| 方向 | 名称 | 说明 | |---|---|---| | 输入 | —— | 无 | | 输出 | —— | 无 |
释放显存(跑图时腾显存)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_FreeMemory)· ComfyUI-AusBoss(MIT)「Free Memory 🆎」,只改类名 / 分类 / 显示名 / 中文文案
任意一根线原样穿过去,顺手把模型卸掉、把显存缓存清空。两段重活之间放一个, 让后一段从空闲显存开始跑,而不是一头撞上爆显存。
- 什么线都能穿 —— 图像、latent、模型、文本、数字;槽类型标
*,接哪都行 - 四步释放,各管各的 —— 卸模型 / 清模型缓存 / 收垃圾 / 清 CUDA 缓存;某步接口改了只跳过那步,线照样通
- 不打缓存 —— 跟别的节点一样只在输入变化时才重跑,下游的缓存不受影响
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 值 | 任意线。这个节点跑的时候清一次显存,然后值原样往下走 |
| 输出 | 值 | 一个字节都没动 |
控制台会打一行 [QG-tools] Free Memory: unloaded models, emptied the model cache, ...,
告诉你哪几步真的做了、哪几步被跳过。
搬运自 ComfyUI-AusBoss「Free Memory」,MIT,保留原出处。
加载文档(把 Markdown 读进工作流)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MDReader)· 作者自有旧插件 ComfyUI-MD-Reader(MIT)「MarkdownFileReader」,合并进来
把一个 .md / .txt 文件读成一路 STRING:提示词、说明文字、术语表写在文件里,
改文件就行,不用回画布上改文本框。文件放进 ComfyUI 的 input 目录就出现在下拉里,
选中之后节点下半部直接把文档显示出来。
- 两种取法 ——
plain把 Markdown 记号(#、*、-、[]()、表格竖线)剥掉, 出来就是能直接当提示词的干净文本;raw原样输出,给需要保留格式的场合 - 也能直接给绝对路径 —— 文档不在这几个目录里时,把完整路径填进
custom_path, 填了就用它、盖过下拉的选择 - 文件变了才重跑 —— 按文件修改时间判断,文档没改就沿用缓存,不会让下游白算一遍
- 编码不乱 —— 依次按 UTF-8(带 / 不带 BOM)、GBK、Latin-1 试过去,中文文档不会读成乱码
- 记住上次选的文件 —— 换工作流、重开页面,下拉还停在你看的那一篇
节点上的预览
选中文件后,节点里就是一块可滚动的预览区:
- 顶栏四个按钮:刷新文件列表(重新扫目录,会提示找到几篇)、放大查看(Esc 关闭)、 复制当前看到的文本、在「渲染后的文档 / 输出的纯文本」之间切换
- 底部一行状态:字符数 · 文件修改时间 · 当前视图
- 预览区跟着节点高度拉伸 —— 节点拖多高它就显示多少,新建时默认给到 380 × 360
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必填) | md_file | 扫描到的文档列表:input 目录 4 层内,以及 ComfyUI 根目录下 md / markdown / prompts / prompt 目录 3 层内;认 .md .markdown .mdown .mdx .txt,最多列 500 个 |
| 输入(必填) | mode | plain 去记号的纯文本 / raw 原文 |
| 输入(可选) | custom_path | 绝对路径;填了就用它,盖过下拉 |
| 输出 | text | 文档正文(STRING,单元素) |
扫描会跳过 .git、__pycache__、node_modules、venv、models、custom_nodes、web、
output 这类目录,免得把依赖包自带的 README 全列进来。一个文档都没有时,下拉里只留
<no document>,节点会提示先放文件再点刷新。
Text(文本)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TextEditOutput)· 参考 ComfyUI_Muye(MIT)「Text Edit Output」的用法,代码自写
画布上的一块随手文本框:在这里敲的字,整段作为一路字符串输出,接给下游任何文本输入 (提示词、文件名、说明文字都行)。
- 整段输出,不切分 —— 多行文本作为一个元素传出,不会因为换行被拆成多路
- 可以接上游 —— 框里的字是默认值;把一根字符串接到
text上,这一次就用上游的, 框里存的内容不动。所以它也能当兜底 - 输出的是「只有一项的列表」 —— 普通字符串消费者(文本编码器、文件名、文本合并) 会被 ComfyUI 自动拆回来,拿到的就是那个字符串;只有声明了列表输入的节点才会拿到列表。 所以接哪儿都行,不用为它挑下游
- 零依赖 —— 纯 Python 输出节点,不加载模型,不需要任何 pip 包
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必填) | text | 手动输入的多行文本;接上游则那一次以上游为准 |
| 输出 | text | 整段文本(单元素 STRING 列表) |
任意切换(动态多输入开关)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_AnySwitch)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiAnySwitch」的用法,代码自写
把任意数量的同类型输入接到节点上,它会输出第一个非空、已连接的那个—— 接线时连几个,节点上的槽位就自动增减(最少 2 个、最多 16 个),中间的空槽会保留位置, 所以优先级稳定、不会因为中间断开而错位。
- 接兜底 —— 把「高清模型」接在最上面、「普通模型」接在下面;前者有就走前者,没有自动回落到后者
- 类型要一致 —— 所有输入必须是同一类型。混接(比如一个 IMAGE、一个 LATENT)节点会直接报错说清是哪两种类型,而不是把错的数据喂给下游
- 全空会报错 —— 一个输入都没接、或全是空值时,节点报错提示,而不是默默传一个
None让下游不明所以地崩
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(可选) | any_01 … any_16 | 任意类型的输入,接到哪个就出现哪个;输出第一个非空 |
| 输出 | any | 第一个非空、已连接的输入(类型与输入一致,连线时槽位会标成具体类型如「图像」) |
展示任意(任意输入预览 + 透传)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_DisplayAny)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiDisplayAny」的用法,代码自写
把任何东西接进 Any 口,节点上直接看到内容,同时原样透传给下游——调试中间结果
不用再挂 SaveImage / 预览一堆不同类型的节点:
- 什么都能看 —— 文本/整数/浮点/布尔直接显示(布尔带红绿配色);图像、遮罩出缩略图; 音频出播放器;视频直接内嵌播放;Latent、张量等显示结构摘要(shape/dtype/device)
- 批量与画册 —— 图像批次自动网格排布,点击放大后 ← / → 键或按钮翻页,Esc 返回
- 文本样式可调 —— 右键「展示文本设置…」可改字号和颜色(INT/FLOAT/BOOLEAN 有默认配色)
- 复制 / 保存 —— 文本悬停出「复制」按钮;图像/音频/视频右键可复制到剪贴板或存盘
- 不影响执行 —— 有下游连接时它按普通依赖执行;没接下游时也会主动执行以刷新预览; 预览转换失败只记日志,数据照常透传,流水线不会断
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(可选) | Any | 任意类型;槽位会按上游输出类型自动标注(图像/模型/CLIP…) |
| 输出 | Any | 输入原样透传,类型一致 |
搬运自孤海工具箱(展示任意 GH),GPL-3.0,保留原出处。
是否判断(布尔懒分支)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_IfElse)· 参考 ComfyUI-Easy-Use(GPL-3.0)「easy ifElse」的用法,代码自写
条件为真透传「真时」的输入,为假透传「假时」的输入——最直白的 if/else:
- 懒执行 —— 没被选中的那一支完全不求值:贵的子图(大模型加载、批量渲染) 挂在没走的那路上不会跑,也不会因为没连东西而报错
- 任意类型 —— 输入输出都是任意类型,图像、模型、字符串都能接; 两路的类型最好一致,输出槽会跟随连线显示具体类型
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 是否为真 | 布尔条件(可接比较节点、开关等的布尔输出) |
| 输入(可选) | 真时 / 假时 | 两条分支的值;未选中的一路不求值 |
| 输出 | 输出 | 被选中那一路的值,类型与输入一致 |
搬运自 Easy-Use(easy ifElse),GPL-3.0,保留原出处。
存在判断(有没有东西过来)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_Exists)
问一句「上游到底有没有东西过来」,顺手把值原样传下去 —— 判定和透传一次办完:
- 判定 —— 有值输出真,没有输出假。输入槽是可选的,所以「没接线」本身就是 一个能判断的状态,而不是执行前的一句报错
- 透传 —— 同一份值从「任意」原样出去,不用把链路拆成两条
- 什么算「没有」 —— 没接线、
None、空文本""、空列表 / 空字典、全黑遮罩、 全零潜空间都算;0和False算有 —— 它们是有效数据,不是缺席; 全黑图像也算有 —— 那是一张有效的黑图,不是失踪 - 判定口径对齐孤海工具箱的「万能是否存在(GH)」 —— 遮罩上低于
0.02的残差当噪声 抹平后再判(Qwen Image 2.1 的 RGBA 存盘再读回来会带 1/255~3/255 的残差,预览是全黑的)。 唯一的区别:我们只判不改 —— 透传出去的值保持原样,不会真把那些像素抹成 0 - 典型接法 —— 「布尔」接到「是否判断」或「布尔开关」的条件上,「任意」接给那一支 要用的下游:可选模型没加载时走兜底,而不是让整张图报错
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(可选) | 任意 | 什么都接;不接 / 空值就是这个节点要报告的状态 |
| 输出 | 任意 | 原样透传进来的值(没接时为空) |
| 输出 | 布尔 | 有值真、没有假 |
输入是「可选」不是「必填」,这点是设计核心:必填的话 ComfyUI 会在执行前就报 「缺少输入」,这个节点永远没有机会输出假。
路由阻断(这条线走不走)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_RouteBlocker)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GoohaiRouteBlocker」的用法,代码自写
串在线路中间的一个开关 —— 通过时它等于一根导线,阻断时按你选的方式处理:
- 仅输出空值 —— 值换成空,下游照常执行,由它自己处理空值。适合「关掉这一段附加 描述」这类仍然要跑完的流程
- 中断后续分支 —— 输出 ComfyUI 原生的执行阻断信号,下游节点被静默跳过,等于 程序化地给这条线按了 Ctrl+M;图里其它分支照跑
- 可以接上游 —— 「是否阻断」是个布尔输入,接布尔开关、比较节点、或另一个「存在判断」 都行,让流程自己决定走不走
- 打开就不花钱 —— 开关打开时,这条线上游的所有节点都不会被求值。所以「条件不满足 就整段不跑」不用再靠把采样器拖出来手动绕过,掐在这里就行:贵的分支一个字节都不花
和「是否判断」的分工很清楚:那个是二选一、只走一条;这个是走不走、走到哪为止, 不用把线路拆成两股,串在任意位置就行。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 是否阻断 | 关着=原样放行;打开=按「阻断模式」处理。可接上游布尔 |
| 输入 | 阻断模式 | 仅输出空值 / 中断后续分支 |
| 输入(可选) | 任意 | 要放行或被阻断的值,什么都接;不接时输出就是空 |
| 输出 | 任意 | 通过时是原值,阻断时是空值或执行阻断信号 |
字符串切换(两段提示词二选一)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_StringSwitch)· 参考 ComfyUI-Crystools(GPL-3.0)「Switch string [Crystools]」的用法,代码自写
同一个节点上放两版提示词,用一个布尔切换输出哪一版 —— 做 A/B 试穿、换风格、开关附加描述时, 不用为每段文字各拉一个文本节点、再各连一根线。
- 两段文本直接写在节点上 —— 上方是「真时文本」,下方是「假时文本」,都不用接线
- 想动态也能接线 —— 把任一文本框拖成输入槽(或直接连上),上游的值会覆盖框里写的
- 没选中的那一路不执行 —— 两个输入都声明了懒执行,挂在假分支上的 LLM 调用、读文件节点不会白跑
- 与「是否判断」的分工:那个切的是任意类型的槽,这个切的是写在节点里的字符串
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 是否为真 | 布尔条件 |
| 输入 | 真时文本 / 假时文本 | 两段文本;既是可编辑框,也能连线上游 |
| 输出 | 字符串 | 被选中的那一段 |
思路参考 Crystools 的
Switch string,按本插件约定重写(显示名、中文 tooltip、惰性判断都不同)。
布尔开关(整张节点就是一枚开关)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_BoolToggle)
一排布尔条件要一起开、一起关时,一个个去点很烦。这个节点把开关本身放到画布上:整张节点就是 一枚开关 —— 左边一块大字,右边一枚胶囊,点胶囊切换,输出接到多少个下游布尔条件上都行, 切一次全部跟着变。
- 可以起名字 —— 双击卡片(或右键「重命名标签…」)给它起个名字,比如「美颜」「高清加强」; 输入框就浮在卡片那几个字上面,回车生效、Esc 放弃,不弹窗;留空就退回「开 / 关」。 一排开关并排时,一眼就知道哪个是哪个
- 一眼看出状态 —— 卡片边框在「开」时变成品牌青色,胶囊滑到右边、底色变绿;名字也随状态 从灰变亮
- 卡片跟着节点等比放大 —— 拉宽节点,字和胶囊一起变大;高度自动跟随(不会被拉成一条细带)
- 状态就是原生布尔 —— 底下仍是一个普通 BOOLEAN 控件(只是被折叠了),存档、撤销、复制粘贴、 API 导出都跟原生节点一致
- 右键也能切 —— 节点右键菜单里有「打开 / 关掉」,不用瞄准胶囊
- 只有胶囊吃点击,卡片其它地方照常拖动节点;四角留给缩放
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 标签 | 卡片上显示的名字,留空则显示「开 / 关」。没有输入槽,双击卡片改 |
| 输出 | 布尔值 | 开关状态,可同时连多个下游;槽名画在卡片上方,不会被卡片压住 |
交互参考 Goohaitools 的「布尔」(孤海);卡片配色、等比缩放、命中区都是本项目自己的实现。
数值(整数 / 浮点合一)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_Number)
一个数字,一张卡片:左边一行小字「值」,右边就是一个数字框 —— 左右拖动改、单击直接输入、右边上下箭头按步进调(Shift 细调), 跟包里 LoRA 加载器的强度框是同一件东西。
- 类型在标题栏齿轮里 ——
?左边那枚齿轮点开是「数值设置」,整数 / 浮点数二选一。 二选一占一整行下拉太浪费,也容易被动到,所以收进齿轮里 - 类型决定输出 —— 选整数就输出
INT(小数四舍五入掉),选浮点就输出FLOAT; 输出槽固定是「任意」(*),所以两种模式都接得进FLOAT口(比如 LoRA 强度) - 步长跟着类型走 —— 整数按 1 走、框里不显示小数点;浮点按 0.1 走、显示两位小数
- 切回整数会取整 —— 卡片里不会有「显示 4、实际 3.7」这种别扭状态
- 值存法跟原生一样 —— 存档、撤销、复制粘贴、API 导出全跟 ComfyUI 自带节点一致
- 一个节点顶两个,不用再纠结拖「整数」还是「浮点数」
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 类型 | 整数 / 浮点数,在标题栏齿轮里切换 |
| 输入 | 值 | 数值本身,拖动 / 单击输入 / 箭头步进 |
| 输出 | 数值 | 类型由「类型」决定,可同时连多个下游 |
输出槽声明为「任意」(
*),因为 ComfyUI 的类型是类级静态的、运行时改不了,真正的 类型由实际返回值决定。别图好看把它改成INT/FLOAT—— 前端会拿它做连线校验, 整数模式就再也接不进FLOAT输入(LoRA 强度),而且connect()是静默失败 (不报错、也不建线),最难查。
数值滑条(范围自己定)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_Slider)
一根滑条挑一个数。跟「数值」的区别只有一个:那边是纯数字框,这边是一根拖得动 的滑条,而且范围自己定(最小 / 最大),适合「强度 0–1」「步数 20–50」这种有明确 上下界的参数。要精确到某一位,点右端的数字直接敲也行。
开箱就是 0 – 1、一格 0.1、输出小数 —— 也就是 LoRA 强度 / 权重 / 去噪强度最常见 的那个区间,新建节点拖两下就能用。要当计数用,在齿轮里把范围改成 0 – 100、类型改成 整数就行。
卡片就一行,从左到右就是用法:
| 位置 | 内容 | 用途 | |---|---|---| | 左 | 滑条轨道 | 唯一的值输入:拖到哪儿值就是多少(一格 = 步长),铺满整行 | | 中 | 当前值 | 实时读数,小数位跟着步长走(步长 0.25 就显示两位);点一下就能直接输入,回车确认、Esc 取消 | | 右 | 齿轮 | 点开「滑条设置」:类型、最小、最大、步长都在这儿 |
- 范围在齿轮里 —— 最小 / 最大一次设好就不常动,所以不占卡片;改完滑条立刻跟着 伸缩,填反了自动对调
- 类型也在齿轮里 —— 整数 / 浮点数二选一,外加步长(浮点模式每格多少,默认 0.1 就是一位小数;0.01 就是两位)
- 整数模式:滑条一格走 1、读数不带小数、切过去时小数会被四舍五入掉
- 浮点模式:滑条一格走「步长」,读数的小数位跟着步长走
- 类型决定输出 —— 选整数输出
INT、选浮点输出FLOAT;输出槽固定是「任意」, 所以两种模式都接得进 LoRA 强度那种FLOAT口(当前是哪种,看右边读数有没有小数位) - 超范围按两端算 —— 无论是拖滑条还是别的插件塞进来的值,出去时都夹在最小值 / 最大值之间;把范围收窄时,现有的值也会被夹回来(不会出现「滑条顶在右端、输出 却是 80」)
- 前后端取整规则一致(
floor(x + 0.5)↔Math.round),不会出现「卡片显示 1、输出 0」 - 数值可以直接敲 —— 点右端的读数弹一个输入框(带出当前值),回车确认、Esc 取消; 打进去的数照样按步长对齐、夹进范围,跟拖出来的没区别
- 轨道又粗又长(12px 高 + 20px 滑块),节点开箱 320×58 —— 跟「布尔开关」 完全一样大,两个摆一排是齐平的;读数只占「范围里最大的那个数」那么宽的格子 (默认 0–1 只有 22px),轨道一直铺到它左缘前 4px(约 237px)
- 画布上这整行是直接画出来的(跟布尔开关同一套做法),所以节点高度能压到 58; Nodes 2.0 下换成 DOM 卡片,高度由卡片自己撑
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 值 | 当前数值,拖滑条改 |
| 输入 | 最小 | 滑条左端,在齿轮里设 |
| 输入 | 最大 | 滑条右端,在齿轮里设 |
| 输入 | 类型 | 整数 / 浮点数,在齿轮里切 |
| 输入 | 步长 | 浮点模式每格多少(整数模式固定 1),在齿轮里调 |
| 输出 | 数值 | 类型由「类型」决定,可同时连多个下游 |
卡片只留了滑条这一个入口:类型、范围、步长都在齿轮菜单里,五个控件本身在画布上 收起来了 —— 存档结构不变,读老工作流照样对得上。
数学运算(一行表达式)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_Math)
卡片上只有一行:写算式。变量是节点左侧的 a、b、c……
需要「宽按高度算」「百分比」「勾股」这类地方,一行写完就行,不用串三个节点。
round(a / b * 2, 2) # 比例算尺寸,留两位
sqrt(a**2 + b**2) # 勾股
100 * 2 # 常数直接写进表达式
a if a > b else b # 取大的那个
- 变量只接上游 —— 左上角默认
a/b/c三个槽,接满一个就自己长出下一个(最多 26 个), 整数(宽度、高度、帧数)、小数、布尔都能接。没连线时按 0 算 —— 要写常数直接写进表达式, 卡片上没有数字框 - 一个结果三种给法 ——
数值(小数)、整数(四舍五入)、布尔(非零为真), 写比较式a > b时直接把布尔当条件接到下游 - 函数用法有专门的手册 —— 📖 数学运算 · 表达式与函数手册:
每个函数做什么、怎么用、有什么上限,都在里面;节点上的
?是速查版 - 算错会说话 —— 语法错、未知名字、除零都会报出原始算式和原因,不会静默返回 0
- 只解析不执行 —— 表达式走语法树白名单,别人分享的工作流带不进代码
| 类别 | 用法 |
|---|---|
| 运算符 | + - * / //(整除) %(取余) **(幂) |
| 比较 / 逻辑 | == != > < >= <=,and or not |
| 条件 | a if a > b else b |
| 常量 | pi e tau |
| 取整 | round(x, n) floor ceil trunc abs sign |
| 数值 | min max sum pow sqrt log log2 log10 exp hypot |
| 三角 | sin cos tan asin acos atan atan2,degrees / radians 换角度 |
| 其他 | int float bool factorial gcd lcm fmod copysign |
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 表达式 | 算式本身,留空输出 0 |
| 输入(可选) | a … z | 自动增长的变量槽,默认露出 3 个;整数 / 小数 / 布尔都能接,没连线按 0 |
| 输出 | 数值 / 整数 / 布尔 | 同一个结果的三种形态 |
^是按位异或(Python 语义),幂请写**。全角的( )+ × ÷和比例写法3:4会自动归一。 每个函数的完整用法和例子见 docs/math.md。
种子(一个数字单独走一根线)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_Seed)· ComfyUI-AusBoss + rgthree-comfy(MIT)「Seed 🆎 / Seed」,只改类名 / 分类 / 显示名 / 中文文案
把种子从采样器里摘出来单独放:一根 INT 线喂给好几个采样器,改一处全部跟着变;
回头想复现某张图,用的哪枚种子就摆在那儿。
卡片从上到下就是一块:大号数字、下面「随机值 / 固定 / Step」三选一、 最底下「新种子 / 用上次 / 历史」。
- 随机值 —— 每次排队之后重新抽一枚,范围 0 – 2⁵⁰−1(故意不铺到 2⁶⁴, 再大 JS 的双精度就丢位了)。新建的节点默认就是这一档
- 手输别超过 2⁵³ —— 框里的数在浏览器里是双精度浮点,填更大的值会被悄悄取整; 上限虽然写的是 2⁶⁴−1,实用区间就在 2⁵³ 以内(随机抽取本来就只到 2⁵⁰)
- 固定 —— 永远用框里这一个
- Step +1 / −1 —— 每次排队之后加一或减一,扫一段连续区间时用
- 它记得自己真正跑过什么 —— 随机值模式一排队,框里的数字就换成下一枚了, 所以「刚出的那张用的哪枚」光看框是看不出来的。节点每次运行会把实际用的值 回传:底下一行「上次运行」显示它,「用上次」把它填回框里并切成固定, 「历史」菜单存最近 8 枚,点一条就填回并固定。历史跟着工作流一起存
- 老工作流照样开 —— v0.8.4 及以前用的是
-1 / -2 / -3哨兵值, 加载时前端翻译成「模式 + 具体种子」,所以现在种子永远是非负整数 - 高度是钉住的 —— 卡片内容固定,拖角落把它拉高只会在下面多一块空白,所以不让拖
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 种子 | 0 – 18446744073709551615;三档模式决定排队后它怎么变 |
| 输出 | 种子 | 本次实际使用的值,可同时连多个采样器 |
搬运自 AusBoss(卡片外观)与 rgthree-comfy(取值与随机逻辑),MIT,保留原出处。
颜色校正(六个滑条走完调色)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ColorCorrect)· 参考 comfyui-art-venture(MIT)「ColorCorrect」的用法,代码自写
六个滑条就是一次完整的调色,不用串一长串节点。它们按摄影调色的顺序依次作用:
色温 → 明度 → 对比度 → 伽马 → 饱和度 → 色调
- 温度 —— 冷暖。负值加蓝、正值加黄。三通道增益按 Rec.709 亮度权重做过归一化, 调它只变色、不会顺带把画面调亮调暗
- 色调 —— 整张图的色相旋转,±180 是一整圈。走 HSV 只转 H,饱和度和明度不动, 纯红转 120 度就是纯绿,不会转出一片灰
- 明度 / 对比度 —— 明度是整体乘系数(-100 全黑、+100 亮度翻倍); 对比度绕中灰 0.5 拉伸(-100 全片变成 0.5 灰)
- 饱和度 —— 按亮度做混合,-100 是纯黑白而且亮度不变,+100 色彩浓度翻倍
- 伽马 —— 只动中间调,两头不动。想提亮暗部又不想冲掉高光时,比直接调明度好用
全程 float 直算:没有 8bit 往返、不逐帧转 PIL、不依赖 OpenCV,所以渐变不出色阶, 整批一次算完。参数回到默认值就跳过那一步 —— 伽马 1.0、其余全 0 时, 输出与输入逐字节相同。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 | 批次一次处理完;有 alpha 通道时原样保留 |
| 输入 | 温度 / 色调 / 明度 / 对比度 / 饱和度 / 伽马 | 见上,六个参数互不干扰,任意组合 |
| 输出 | 图像 | 与输入同尺寸、同批次数 |
颜色匹配(把一张图的配色搬到另一张)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ColorMatch)
给它一张目标图和一张参考图,它把参考图的色调、对比、整体色偏搬过来, 目标图自己的构图和明暗层次保留。典型用法:把生成图和一张实拍素材的色调对齐、 给一段视频统一成同一个影调、把不同来源的素材剪在一起时统一配色。
九种方法(另加一个仅均值),按「换色换到多狠」排列:
| 方法 | 干了什么 | 什么时候用 |
|---|---|---|
| 小波变换 | Haar 小波分解 3 层,只把最低频子带的均值 / 方差对齐到参考,细节子带原样保留 | 素材细节多(布料、皮肤、毛发、文字)。换色调但纹理、边缘、噪点全不动 |
| 自适应实例统一化 | AdaIN 的逐通道 (x-μ)/σ,在 sRGB 上做 | 同源素材、风格化迁移。比莱因哈德更"硬",不分离亮度与色度 |
| 最大均值差异 | RBF 核下最小化 MMD²(P′,Q),迭代 60 步求出一组仿射映射 | 参考图的分布是多峰的、不像高斯时,比协方差法更贴 |
| 直方图匹配 | 逐通道按分位数把分布重排成参考的(CDF 匹配) | 要"完全一致"时。均值方差偏斜全对上,也最容易失真 |
| 莱因哈德色彩迁移 | 转到 CIELAB 后逐通道 (x-μ)/σ 对齐(Reinhard 2001) | 默认就用它。亮度和色度解耦,改色不改明暗层次 |
| 多元高斯分布 | LAB 上做 3×3 协方差匹配(Pitié 2007 线性 MKL 的核心:白化再着色) | 修色偏最干净。比逐通道多照顾通道之间的相关性 |
| 直方图匹配-多元高斯分布-直方图匹配 | 三步串联:先把边缘分布拉近,再纠正相关性,最后直方图收尾 | 要边缘分布也对得很准。比单次直方图稳一点 |
| 直方图匹配-最大均值差异-直方图匹配 | 同上,中段换成核均值匹配 | 同上,且参考分布明显非高斯 |
| Reinhard Lab GPU算法 | 与莱因哈德同一个数学,但走整批 4D 张量广播,没有逐帧循环 | 大图、长批次、跑在 GPU 上时更快。结果与莱因哈德逐像素一致 |
| 仅均值 | 只搬平均色,不动对比度 | 最保守。只想换掉整体色偏、不想动观感时 |
几个实现上的取舍:
- 小波只动低频是有意的 —— 连细节子带一起匹配会把纹理改掉,那就成"重绘"了
- MMD 求的是仿射映射,不是逐像素核回归。后者数学上更"正宗",但 E[Y|X] 的方差 不可能大于 Y 的方差,实测输出 σ 只剩参考的四成,画面发灰;仿射版一阶 / 二阶统计 都对得上,图像自身的局部结构也原样保留
- "直方图匹配-…-直方图匹配"里中间那步的参考不变,三步都对着同一张参考图, 不是逐级传递
- 出口不再硬裁 —— 匹配后落到 sRGB 外面的颜色,沿 LCh 的 C 轴缩饱和度(色相与 明度都不动)。逐通道 clamp 会改掉三原色比例,也就是改色相(实测饱和色偏 2–8°), 这是 W3C 色域映射指南明确要求避免的
- 源侧统计量有下限 —— 目标图本身很平(雾、纯色背景、欠曝暗部)时,σ 会小到 σ参考/σ源 放大几十倍,噪声和色阶一起炸出来。下限设成归一化 L 的 2%(约 5/255), 实测同一张近纯色图:无下限偏离 0.12,有下限 0.013
- 遮罩有两个作用,别混 —— 一个是「结果作用在哪」,一个是「统计量从哪取」。 后者是 Photoshop 匹配颜色的「使用选区计算颜色」:把主体贴进新背景时,背景像素 不该参与目标侧的均值 / 协方差,否则主体统计被稀释。实测一张主体在左、右半是 强绿的图,不限定统计时结果被带偏 0.17(归一化 Lab),限定后精确落到参考均值
- 参考图也能单独接遮罩 —— 参考图里有大片无关内容(天空、水面、水印、字幕)时, 只让选中的区域参与统计。实测参考图左半暖橙、右半冷蓝,全图统计会把结果拉到 中间(b −0.06),只在左半统计后 b 升到 0.21、贴着左半的真实值
- 细节回填补的是差额,不是原值 —— 直方图匹配把低对比素材拉宽时,颗粒和噪声 会被一起放大(文献里叫 grain effect,实测高频能量 0.047 → 0.086);反过来压缩 时细节又被抹平。按「原图高频 − 结果高频」补,两种方向都能还原,且差额逐通道去 均值,实测 sRGB 通道均值变化 < 1e-4,只动纹理不动明暗
- 小波变换不吃统计遮罩 —— 它是逐图对齐低频子带,本来就不统计像素分布,
所以
遮罩用途/参考遮罩对它只影响「作用区域」,不影响匹配本身
通用参数:
- 强度 —— 结果与原图的线性混合。0 = 原图,1 = 完全匹配,0.5 左右通常最自然 (留一半原图的味道)。想做「轻微统一影调」就别拉到 1
- 参考取帧 —— 参考图是批次时:
全部合并(所有帧并成一个样本池统计,最稳)/仅第一帧/逐帧对应(参考帧数不够就循环取) - 目标统计 —— 目标图是批次时源侧统计怎么算:
逐帧(每帧各算一套,单张图最贴)/全批统一(整批合成一套,帧与帧之间的相对差异被保留,视频不会闪)。 视频 / 序列 / AnimateDiff 一律用全批统一;只有一帧时两者等价 - 匹配范围 ——
全部(明暗和色度都换)/仅色度(保留原图的明暗层次,只换色调)/仅明暗(保留原图色调,只换对比度与整体亮度)。合成、只想统一影调时很有用 - 遮罩用途 ——
仅结果(只决定作用区域,统计量仍取全图)/也限定目标统计(统计量也只从遮罩内取)。把主体贴进别的背景时用后者,背景不会再稀释主体统计 - 细节回填 —— 把高频(纹理、颗粒、边缘锐度)还原到原图的水平。直方图匹配把 渐变拉成色块、或者把低对比素材的噪点拉炸时调到 0.3–0.6;0 = 不管
- 遮罩羽化 —— 遮罩边缘的高斯羽化宽度(像素),0 = 硬边。接遮罩做局部换色时 设 8–32,接缝会消失
- 遮罩 —— 作用区域:白色处应用匹配,黑色处保留原图。做局部换色、 或者只想统一背景色调时接一张遮罩即可
- 参考遮罩(可选)—— 参考图上的统计区域:只有白色处的像素参与统计。 参考图里有大片无关内容(天空、背景、水印)时接一张,配色不会被它们带偏
参考图不需要和目标图同尺寸 —— 取的是统计量,不是逐像素对应。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 | 要改的目标图;批次逐帧处理,有 alpha 通道时原样保留 |
| 输入 | 参考图像 | 配色从它身上取,尺寸随意 |
| 输入 | 方法 | 九种 + 仅均值,见上表,默认「莱因哈德色彩迁移」 |
| 输入 | 强度 | 0–1,默认 1.0 |
| 输入 | 参考取帧 | 全部合并 / 仅第一帧 / 逐帧对应,默认全部合并 |
| 输入 | 目标统计 | 逐帧 / 全批统一,默认逐帧 |
| 输入 | 匹配范围 | 全部 / 仅色度 / 仅明暗,默认全部 |
| 输入 | 遮罩羽化 | 0–256 像素,默认 0(硬边) |
| 输入 | 遮罩用途 | 仅结果 / 也限定目标统计,默认仅结果 |
| 输入 | 细节回填 | 0–1,默认 0(不补) |
| 输入 | 遮罩(可选) | 作用区域,不接就是全图 |
| 输入 | 参考遮罩(可选) | 参考图上的统计区域,不接就是整张参考图 |
| 输出 | 图像 | 与目标图同尺寸、同批次数 |
全程 float 直算,LAB 走 sRGB → 线性 → XYZ → Lab(D65),出界颜色缩 chroma 后再
clamp 回 [0,1],中间不做 8bit 往返,所以渐变不出色阶。小波用正交归一化 Haar,
正逆变换往返误差在 1e-7 量级。
图像水印
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ImageWatermark)· 参考 ComfyUI_Muye(MIT)「AddImageWatermark」的用法,代码自写
把一张水印图贴到底图上,全程留在工作流里,不用导出再进修图软件。
- 四种缩放 —— 不缩放 / 等比适配(缩到能放进底图)/ 按倍数 / 按指定宽高
- 九宫格定位 —— 九个锚点任选,再用横向 / 纵向像素偏移做微调(右下角默认偏 32px)
- 可旋转、可半透明 —— 旋转后画布自动扩大不裁角;透明程度 0 完全不透明、100 完全透明
- 遮罩限定 —— 可选接一张遮罩,白色区域不透出水印,做不规则留白很方便
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 底图 | 可以是批次,水印逐帧贴 |
| 输入 | 水印图 | 接批次时只用第一帧 |
| 输入 | 缩放模式 / 缩放算法 / 缩放倍数 / 目标宽 / 目标高 | 缩放相关;只有对应模式生效 |
| 输入 | 锚点位置 / 横向偏移 / 纵向偏移 / 旋转角度 / 透明程度 | 定位与外观 |
| 输入(可选) | 遮罩 | 白色区域不透出水印 |
| 输出 | 图像 | 张数与底图一致 |
搬运自 ComfyUI_Muye(添加图像水印),MIT,保留原出处。
文字叠加图像
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TextOverlayImage)· 参考 ComfyUI_Muye(MIT)「TextOverlayImage」的用法,代码自写
把一段文字直接画进画面,字体、字号、颜色、横排竖排都能调。
- 按中心点定位 ——
中心 X/中心 Y是文字块的中心,不是左上角,挪起来更直观 - 横排 / 竖排 —— 竖排逐字换行,适合做竖排标题
- 颜色两种给法 —— 内置六色下拉,或接一个
[R, G, B]三元组(0-255 或 0-1) - 附带文字遮罩 —— 同时输出
遮罩(白=有字),可以拿去做局部处理
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 | 批次时每帧都画同样的字 |
| 输入 | 文字 / 字体 / 字号 | 文字内容与字形(字体读的是系统字体目录) |
| 输入 | 内置颜色 / 排版方向 / 中心 X / 中心 Y | 外观与位置 |
| 输入(可选) | 自定义 RGB | 接了就不看内置颜色 |
| 输出 | 图像 / 遮罩 | 画好的图 + 文字形状遮罩 |
搬运自 ComfyUI_Muye(文字叠加图像),MIT,保留原出处。
宫格图像拼接
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ImageGrid)· 参考 ComfyUI_Muye(MIT)「MuyeGridImageConcat」的用法,代码自写
把多张图拼成一张宫格图,结果直接在节点上预览。
- 最多 16 张 —— 接批次张量或张量列表都行
- 统一尺寸 —— 开:所有格子跟第一张同尺寸,图在格内等比居中不裁剪;关:各图保持原尺寸
- 剔除全黑帧 —— 上游批次节点给未接输入补的黑图占位会污染宫格,默认丢掉;不需要可关掉
- 间隙与背景 —— 格子之间的像素间隙、以及间隙/留白的填充色(黑 / 白)
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像列表 | 批次张量或列表,最多取前 16 张 |
| 输入 | 统一尺寸 / 剔除全黑帧 / 格子间隙 / 背景色 | 排布选项 |
| 输出 | 图像 | 拼好的宫格图(同时在节点上预览) |
搬运自 ComfyUI_Muye(宫格图像拼接),MIT,保留原出处。
遮罩上色
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MaskColorize)· 参考 ComfyUI_Muye(MIT)「MaskColorize」的用法,代码自写
把遮罩区域涂成一块纯色,用来肉眼检查遮罩,或者在局部重绘前先把区域烧平。
- 六种内置色 —— 黑 / 白 / 灰 / 红 / 绿 / 蓝,也能接
[R, G, B]自定义 - 0.5 硬切 —— 软边遮罩按 0.5 阈值当硬边处理,涂出来边界干净
- 支持批次 —— 单张遮罩会应用到整批;一帧一遮罩则各涂各的
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 底图 / 遮罩 | 遮罩白色(>0.5)区域涂色,黑色保留原图 |
| 输入 | 内置颜色 | 六选一 |
| 输入(可选) | 自定义 RGB | 接了就以它为准 |
| 输出 | 图像 | 上色后的图像 |
搬运自 ComfyUI_Muye(遮罩区域上色),MIT,保留原出处。
遮罩拼接
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MaskConcat)· 参考 ComfyUI_Muye(MIT)「MaskConcatenate」的用法,代码自写
两张遮罩左右或上下拼成一张。
- 两个方向 ——
左右沿横向拼,上下沿纵向拼 - 统一尺寸 —— 开:把较小的遮罩拉伸到较大遮罩的尺寸;关:各保持原尺寸
- 标准张量 —— 输出
(1, H, W),下游按 MASK 取维度不会错位
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 遮罩 1 / 遮罩 2 | 要拼的两张遮罩 |
| 输入 | 统一尺寸 / 拼接方向 | 排布选项 |
| 输出 | 遮罩 | 拼好的遮罩 |
搬运自 ComfyUI_Muye(遮罩拼接),MIT,保留原出处。
遮罩精修
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MaskRefine)· 参考 ComfyUI-AusBoss(MIT)「Mask Refine 🆎」的用法,代码自写
把一张遮罩按固定顺序修一遍,顺序是定死的,不用自己拼节点:
扩缩 → 补洞 → 平滑 → 羽化 → 边缘精修 → 色阶
- 扩缩 —— 按整像素往外长或往里收,可分离 max / min 池化,跑多远都是两趟
- 补洞 —— 只补被围住的窟窿,碰到画面边缘的缺口永远不算洞;
最大补洞按面积百分比限制,2% 能补掉随手一笔的缝但保住你故意没涂的人 - 平滑 —— 二值化 → 高斯 → 再二值化,只把差值加回去:锯齿被化掉了,软边遮罩原来的 alpha 一点没丢
- 羽化 —— 可分离高斯,0 保持硬边
- 边缘精修 —— 拿导向图把边吸附到发丝、衣领上;导向滤波要
opencv-contrib-python,抠像要pymatting,没装只会报一句明确的缺依赖提示,不影响其它设置 - 色阶 —— 黑白场收一遍,把软分割留下的灰雾抹干净
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 遮罩 | BHW 遮罩,白=选中 |
| 输入 | 扩缩 / 羽化 | 像素级放大缩小、高斯羽化强度 |
| 输入 | 补洞 / 最大补洞 | 补不补洞、最多补到画面的百分之几 |
| 输入 | 平滑 | 化掉锯齿的像素数,不加羽化 |
| 输入 | 边缘精修 / 导向图 | 关 / 导向滤波 / 抠像;选了后两个要接导向图 |
| 输入 | 黑场 / 白场 | 色阶,最后一步 |
| 输入(可选) | 预览 | 把结果画在节点脸上,默认开 |
| 输出 | 遮罩 | 修好的遮罩 |
| 输出 | 反相遮罩 | 取反,给处理背景的节点用 |
搬运自 ComfyUI-AusBoss「Mask Refine」,MIT,保留原出处。
遮罩裁剪 / 裁剪恢复
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MaskCrop)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GH_MaskCropV2」的用法,代码自写 来源:原创(QG_CropRestore)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「GH_CropRestore」的用法,代码自写
一对配套节点,走的是「裁小的那块去处理,处理完贴回原位」:
按遮罩取材 → 送去放大 / 重绘 → 贴回
- 遮罩裁剪 —— 按画好的遮罩量出包围盒,四边各自留出可调的余量(相对遮罩最短边的倍数,1.4 就是多留 40%),再规整成 8 的倍数好进 latent。裁到画面外的部分用它自己的边缘颜色填上,而不是抹黑
- 裁剪恢复 —— 把处理过的裁剪图缩回原来的矩形,通过遮罩混回原图。遮罩以外的像素与原件逐像素相同,整张图其余部分一个像素都不经过缩放
尺寸有三种取法:
| 尺寸模式 | 做什么 | 什么时候用 |
|---|---|---|
| 原尺寸 | 遮罩 + 余量,向上取整到倍数 | 最常见的「裁出来正好」 |
| 正方形 | 补成最大边长的正方形 | 要喂只吃方图的分辨率档位 |
| 自定义 | 按指定宽高取景(cover,不是 fit) | 模型要求 1024×1024 之类 |
自定义 只填一边、另一边填 0 时,0 的那边按比例推出来。取景是 cover:先把矩形按目标比例补宽或补高,再缩到目标尺寸,所以主体不会被压窄,多出来的部分是填色。
输入 / 输出
遮罩裁剪
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 / 遮罩 | 要裁的画面,和要留住的范围 |
| 输入 | 尺寸模式 | 原尺寸 / 正方形 / 自定义 |
| 输入 | 自定义宽 / 自定义高 | 只在自定义下用,默认 1024 × 1024 |
| 输入 | 倍数取整 | 向上取整到它的整数倍,默认 8;1 关闭 |
| 输入 | 上扩展 / 右扩展 / 下扩展 / 左扩展 | 遮罩最短边的倍数,1.0 紧贴边缘 |
| 输入 | 遮罩补洞 | 先补上遮罩自己围住的窟窿再量尺寸 |
| 输入 | 填充方式 | 边缘取色 / 边缘拉伸 / 黑色 |
| 输出 | 接缝 | 恢复用的全部信息(原图 + 矩形 + 裁剪尺寸),接到裁剪恢复 |
| 输出 | 裁剪图像 / 裁剪遮罩 | 裁出来的一块 |
裁剪恢复
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 接缝 / 图像 | 裁剪的接缝 + 处理完的裁剪图(尺寸随意,会缩回去) |
| 输入 | 遮罩扩张 | 贴之前把遮罩放大几像素,4~16 能盖住重绘的接缝 |
| 输入 | 羽化 | 边在这多像素里过渡,0 是硬边 |
| 输入 | 颜色对齐 | 中位配色对齐,消掉缩放往返留下的明度漂移 |
| 输入(可选) | 裁剪遮罩 / 背景图像 | 改过的裁剪遮罩;换个背景贴 |
| 输出 | 图像 | 贴回后的整张图 |
整批(多帧)共用一个裁剪矩形(所有帧遮罩的并集),所以视频不会一帧一个取景地抖。
还没画遮罩时不会报错 —— 整张图原样通过(日志里提示一句)。这一步通常是工作流还没画完, 不该为此中断整条流程。画好之后再跑就是正常裁剪。
自写。功能对位孤海工具箱(GPL-3.0)「遮罩裁剪V2 / 裁剪恢复」,代码重写。
遮罩对齐
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_MaskAlign)· 参考 孤海工具箱 Goohaitools-comfyui(GPL-3.0)「孤海-遮罩对齐」的用法,代码自写
把画好的区域平移过去,和另一张遮罩对齐;不接参考就对齐到画布本身。
水平 和 垂直 各自选锚点:
| 锚点 | 效果 |
|---|---|
| 居中 | 把主体居中放进参考里 |
| 左对齐 / 上对齐 | 两条近边贴齐 |
| 右对齐 / 下对齐 | 两条远边对齐 |
| 不动 | 这个轴原样保留 |
输出两选一:遮罩 是搬动后的遮罩本身(软边一起搬,不会被重画成硬边矩形),外接框 是盖住落点的实心矩形——外接框正是裁剪节点想接的东西,勾上 合并外接框 还会把参考的框一起框进去。
整批只算一个偏移(包围盒取并集),视频的帧因此保持对齐,不会各自漂几个像素。
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 遮罩 | 要移动的遮罩 |
| 输入 | 水平对齐 / 垂直对齐 | 各自的锚点 |
| 输入 | 输出 | 遮罩 / 外接框 |
| 输入 | 合并外接框 | 外接框模式下连参考的框一起框 |
| 输入(可选) | 参考遮罩 | 对齐参照;任何不是全透明的地方都算 |
| 输出 | 遮罩 | 移动后的遮罩,尺寸不变 |
自写。功能对位孤海工具箱(GPL-3.0)「遮罩对齐v2」,代码重写。
重绘裁剪 / 重绘缝合
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_CropForInpaint)· 参考 ComfyUI-AusBoss(MIT)「Crop For Inpaint 🆎」的用法,代码自写 来源:原创(QG_StitchInpaint)· 参考 ComfyUI-AusBoss(MIT)「Stitch Inpaint 🆎」的用法,代码自写
一对留给「重绘」的节点:重绘裁剪 按遮罩把要画的地方裁出来,重绘缝合 把画完的结果贴回去。
跟 遮罩裁剪 → 裁剪恢复 的分工:
| | 遮罩裁剪 → 裁剪恢复 | 重绘裁剪 → 重绘缝合 |
|---|---|---|
| 用途 | 纯几何裁剪,切出来给放大、换脸、单独处理 | 重绘 / 扩图,模型要看得懂周边 |
| 上下文 | 按最短边倍数扩边 | 上下文倍数 + 额外上下文,还能按目标面积重采样 |
| 贴回 | 硬贴,只按羽化混 | 羽化混 + 色调匹配 + 边缘光环修复 + 沿画面自身边缘渐变 |
| 数据 | 自家一对 QGSeam | AUSBOSS_STITCHER,和 AusBoss 互通 |
重绘裁剪
按遮罩包围盒裁出区域,四周带上下文,缩放到采样器接受的尺寸,同时输出一份缝合数据。
上下文倍数—— 1.0 紧贴遮罩,1.2 是默认值贴回羽化—— 只羽化贴回那条边,不动采样遮罩;要改重绘范围用遮罩扩缩/遮罩羽化目标面积/目标宽高—— 把裁剪图缩放到目标尺寸,尺寸对齐保证能被采样器接受向左 / 右 / 上 / 下扩—— 直接长画幅,这就是它的扩图用法不越界(默认开)—— 上下文碰到画面边缘就停,模型只看到真实像素
三个输出:裁剪图像、采样遮罩、缝合数据。
遮罩是空的就选整张画面,缝合回来原样不动。核心「加载图像」没画遮罩时给的 64×64 占位算「空」不算「错」,不会把整条 prompt 拦下来。
重绘缝合
缝合数据—— 接重绘裁剪;扩图接了补边画布时,也可以接裁剪 + 旋转 + 补边重绘图像—— 采样器出来的结果;尺寸被采样器改过也没关系,会先缩放回裁剪窗口接缝方式——经典贴回(默认,既有工作流都是它)/融入画面(扩图、斜着转更自然,沿画面自身边缘渐变交给原图)色调匹配—— 新区回来偏亮、偏暗或偏暖时往回调,需要羽化才有意义边缘光环修复—— 羽化接缝留下一圈暗边或亮边时打开,需要可选的pymatting
缝合没碰到的像素与原始画面逐位相同,不经过任何缩放。混合遮罩 标出改动范围,可以接色调匹配或合成节点。
和 AusBoss 互通
槽类型是 AUSBOSS_STITCHER、数据里的 kind 是 ausboss_inpaint_stitcher,这两个字符串故意保留原样:两个插件都装时,任意一边的裁剪都能喂任意一边的缝合,结果逐像素一致(tools/_check_stitch_inpaint.py 里 52 项断言守着这条)。改名会让两边互相不认识,老工作流直接断线。
文本替换
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TextReplace)· 参考 ComfyUI_Comfyroll_CustomNodes(MIT)「CR_TextReplace」的用法,代码自写
最多三组「查找 → 替换」,一次配好一整条清洗链。
- 模式可选 ——
字面(默认):括号、点号、竖线、反斜杠都是普通字符,提示词里的(red:1.3)能被整段删掉;正则:按正则表达式处理,替换内容可用\1反向引用,正则写错会直接报错 - 三组规则 —— 按 1 → 2 → 3 顺序生效,后面的规则看到的是前面的结果
- 留空跳过 —— 某组查找留空就整组跳过。上游这里会把替换内容插到每个字符之间
(
hello→XhXeXlXlXoX),QG 加了防护,误填替换内容也不会毁文本
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(必连) | 文本 | 要改的文本,从上游连过来 |
| 输入(下拉) | 模式 | 字面 / 正则,默认字面 |
| 输入(可选) | 查找 1 / 替换 1 … 查找 3 / 替换 3 | 三组替换规则 |
| 输出 | 字符串 | 替换后的文本 |
搬运自 Comfyroll Studio(
CR Text Replace),MIT,保留原出处。
旧工作流自动迁移:v0.9.3 及更早的这一节点是从别处搬的,
文本是节点里直接打的 文本框、还多一个「文本列表」槽。现在文本改成只能从上游接,打开旧存档时会自动 把模式归位、给原来那段手打的文本补一个「多行文本」节点接上、摘掉空着的「文本列表」槽。 旧存档里如果「文本列表」接着线,那条线不会被动,需要你把上游改接到文本上。
文本按分隔符分割
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TextSplit)· 参考 ComfyUI_Muye(MIT)「TextSplitByDelimiterEnhanced」的用法,代码自写
按分隔符切文本,默认分隔符就是 <think>——正好切掉模型的思考块。
- 三路输出 ——
全部段落(所有输入切完的合集)、单条切分(选定那条输入的完整切分)、指定段落(第 N 段) - 各自带索引 —— 三路输出的取用位置分别由
汇总序号/列表序号/段落序号控制(从 1 开始,0 = 空) - 支持正则分隔 —— 打开
使用正则,分隔符按正则表达式解释
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 输入来源 | 文本框 用下面的单段文本;外部列表 用接进来的 外部文本列表 |
| 输入 | 文本 / 分隔符 / 使用正则 | 切分依据 |
| 输入 | 段落序号 / 列表序号 / 汇总序号 | 三路输出的取用位置 |
| 输入(可选) | 外部文本列表 | 外部列表 模式下的输入 |
| 输出 | 全部段落 / 单条切分 / 指定段落 | 前两路是列表,第三路是单段字符串 |
搬运自 ComfyUI_Muye(文本按分隔符分割),MIT,保留原出处。
文本合并(两段拼一段)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_TextConcat)· 参考 ComfyUI_Comfyroll_CustomNodes(MIT)「CR_TextConcatenate」的用法,代码自写
text1 + 分隔符 + text2。两个文本输入都是槽(必须从上游连过来),分隔符是控件。
- 不做任何 trim —— 空串和
b用-连起来就是-b。想要空格就把空格填进 分隔符;想做主体, 修饰这种就填, - 分隔符原样插入 —— 填换行就换行,填
|就是竖线,不做转义 - 上游那个废输出删掉了 —— 原版声明了两个输出口,但函数只返回一项, 第二个口永远拿不到值;搬过来时去掉了
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 文本1 / 文本2 | 要拼的两段,都从上游连进来 |
| 输入 | 分隔符 | 中间插的东西,原样照抄 |
| 输出 | 字符串 | 拼好的整段 |
搬运自 Comfyroll Studio(
CR_TextConcatenate),MIT,保留原出处。
Google 翻译(提示词对翻)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_GoogleTranslateText)· 参考 ComfyUI_Custom_Nodes_AlekPet(MIT)「GoogleTranslateTextNode」的用法,代码自写
把提示词在中文和外语之间对翻。接在文本编码前面,就能「中文写、英文出」。
- 默认走免费端点 —— 不用 key,就是 Google 网页翻译用的那个接口;同一 IP 段被 限流(HTTP 429)时会失败
- 有 key 就优先用官方接口 —— 设好环境变量
GOOGLE_TRANSLATION_API_KEY, 就走translation.googleapis.com,配额内不限速 - 两条路各试一次 —— 先按你配置的代理走(尊重系统代理 / 环境变量),失败再绕开 一切代理直连重试(连接 6 秒、读取 20 秒)。这条是为「代理连不上 Google、 直连反而通」和「直连抽风」两种情况准备的
- 失败就原样吐回去 —— 翻译不通时节点把输入原封不动传下去,控制台留一行日志。 工作流不会因为网络断了就整条跑不下去
- 手动翻译 —— 打开
手动翻译,节点排队时完全不联网、只把文本原样透传;这时点 节点上那枚Manual Translate按钮才会真的翻一次,译文直接写回文本框, 看得见也改得动。开关没打开时点它只会提示「翻译在排队时进行」 - 零新增依赖 —— 上游依赖
googletrans包;这里用 ComfyUI 自带的requests直连同一批端点,语言表内嵌(100 多种语言代码)
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 源语言 | 默认 auto,让 Google 自己判断 |
| 输入 | 目标语言 | 默认 en |
| 输入 | 手动翻译 | 打开则只透传、不联网 |
| 输入 | 文本 | 要翻的原文 |
| 输出 | 文本 | 译文;失败时等于原文 |
搬运自 ComfyUI_Custom_Nodes_AlekPet(
GoogleTranslateTextNode),MIT,保留原出处。
尺寸选择器
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_SizeSelector)· 参考 ComfyUI_Muye(MIT)「MuyeSizeSelector」的用法,代码自写
选好比例,节点直接给出空 Latent 和实际宽高。
- 预设 + 自定义 —— 预设列表覆盖常见比例;也可以在
比例里自己填16:9、2.39:1、1 1 - 长边缩放 ——
长边填 0 用预设原始尺寸,填 N 就把长边缩到 N 并保持比例 - 百万像素 ——
百万像素填1.0/2.0就按面积定尺寸,形状仍由比例决定 - 潜在通道数 —— 4 给 SD1.5 / SDXL,16 给 Flux / SD3 / 视频模型(上游写死 16,这里是可选的)
- 帧数与对齐 ——
帧数大于 0 即视频模型;对齐倍数把宽高贴到 8/16/32 的倍数上 - 比例不漂移 —— 比例和对齐倍数同时生效时按
w = rx·k、h = ry·k求解,两个方向 同时落在网格上、比例仍然精确;上游是「先改比例、再各自向上取整」,会漂(16:9 在 32 下 曾被算成 1344×768 = 7:4) - 自动适配模型的下采样倍数 —— 输出的 Latent 会声明「按 8 倍下采样做的」,16 倍的模型 (Qwen Image 2.x、Flux 2 Klein)由采样器自己换算;缺了这个声明,出图会正好是设定值的两倍
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 预设尺寸 / 批次大小 | 起手尺寸与批大小 |
| 输入 | 长边 / 比例 / 帧数 / 对齐倍数 / 潜在通道数 | 尺寸微调 |
| 输入(可选) | 宽(覆盖) / 高(覆盖) | 接任意数值,大于 0 就优先用它 |
| 输入(可选) | 百万像素 | 0 = 不用;非 0 就按这个面积定尺寸 |
| 输出 | Latent / 宽 / 高 / 帧数 | 空潜在张量 + 实际使用的数值 |
搬运自 ComfyUI_Muye(尺寸选择器),MIT,保留原出处。
空 Latent 分辨率(比例 + 百万像素一步出 latent)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_EmptyLatentResolution)· 作者自有旧插件 ComfyUI-EmptyLatentResolution(MIT)「EmptyLatentResolution」,合并进来
官方的「分辨率选择器」算宽高、官方的「空 Latent」吃宽高,中间得连两根线。这个节点把两步合成一步: 选比例、给百万像素,直接出空 Latent,同时把算好的宽高也送出去。
- 省掉两根线 —— 宽高在节点内部算完就用了,
width/height同时作为整数输出, 下游要拿尺寸的地方不用再挂一个测量节点 - 八种比例,写的是摄影叫法 ——
1:1/3:2/2:3/4:3/3:4/16:9/9:16/21:9, 下拉里标成 Square / Portrait Photo / Widescreen 这些,带 Portrait 的是竖图 - 按面积定尺寸 ——
百万像素填1.0/2.0就按总像素算,形状仍由比例决定: 1.0 MP 在 1:1 下约 1024×1024,2.0 MP 在 3:4 下是 1256×1672 - 对齐倍数可调 ——
对齐倍数默认 8(和 latent 的 8 倍下采样对齐),16 / 32 / 64 给新一代模型用; 宽高先向倍数取整再对齐,不会出现半格 - 和官方算出来的一样 —— 尺寸算法与官方
ResolutionSelector逐行一致(同样的sqrt缩放、 同样的 multiple 取整),8 种比例 × 4 档百万像素 × 4 档倍数的 128 组参数实测逐个相同; latent 结构也与官方EmptyLatentImage一致(4 通道、同样的intermediate_device/intermediate_dtype、同样带downscale_ratio_spacial=8)—— 所以把原来那两个节点换成这一个, 出图尺寸不会变 - 节点上直接看得到结果 —— 自带分辨率预览框,拖比例或百万像素时实时画出得到的形状, 不用先跑一遍才知道算出多少
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 宽高比(aspect_ratio) | 八种预设比例,决定形状 |
| 输入 | 百万像素(megapixels) | 目标总像素(百万),决定大小 |
| 输入 | 批量大小(batch_size) | 一次出几张空 latent |
| 输入(高级) | 对齐倍数(multiple) | 宽高向这个倍数取整,默认 8 |
| 输入(可选) | 分辨率预览(preview) | 预览控件,读上面三个控件,不参与提交 |
| 输出 | Latent / 宽 / 高 | 空潜在张量 + 最终像素宽高 |
图像缩放(像素或百分比,crop / pad / contain)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ImageResize)· 参考 rgthree-comfy(MIT)「RgthreeImageResize」的用法,代码自写
给一个目标尺寸把图缩过去,顺手把实际宽高当整数输出,下游要算尺寸的地方 不用再接一个测量节点。
- 两种度量 ——
pixels填绝对像素;percentage填相对原图的百分比 - 宽或高填 0 = 由另一边按比例推算 —— 只给一边就行,这时强制按
contain走 - 三种贴合方式 ——
crop放大铺满再居中裁掉多余(输出恰为目标尺寸)/pad缩到装得下再居中补黑边(输出恰为目标尺寸)/contain缩到装得下就返回 (某一侧可能小于目标,不裁不补) - 原尺寸直通 —— 目标宽高与原图一致、或两个都填 0 时,图原样返回,不重采样, 所以「尺寸算下来没变」这条链上不会白丢一次画质
- 重采样用的就是 ComfyUI 自己那套 —— 下拉列表直接取原生
ImageScale的方法表, 装了什么插件扩展的算法这里也都会有
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 | 要缩放的图像 |
| 输入 | 度量方式 | pixels(像素)/ percentage(百分比) |
| 输入 | 宽 / 高 | 目标宽高;填 0 表示由另一边推算 |
| 输入 | 适配方式 | crop / pad / contain |
| 输入 | 缩放算法 | 与原生 ImageScale 同一份列表 |
| 输出 | 图像 / 宽 / 高 | 缩放结果 + 实际宽高(整数) |
搬运自 rgthree-comfy(
RgthreeImageResize),MIT,保留原出处。
图像或 Latent 尺寸(一个入口读宽高)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ImageOrLatentSize)· 参考 rgthree-comfy(MIT)「Image or Latent Size」的用法,代码自写
接什么都行 —— 图像、遮罩、Latent,节点只回 宽 / 高 两个整数。
- Latent 自动 ×8 —— Latent 里存的是下采样之后的尺寸(
(B, 4, H/8, W/8)), 这里乘回去,给你真实的像素尺寸 - 遮罩和图像靠维度自动分 ——
(B, 1, H, W)当遮罩、(B, H, W, C)当图像 - 没接东西就回 0 / 0 —— 不报错,方便先把线拉好再连上游
- 典型用法:接在「图像缩放」之后看实际尺寸、给「按当前尺寸算缩放比例」的分支提供输入、 超分之前先确认原图多大
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入(可选) | 输入 | 图像 / 遮罩 / Latent 都收 |
| 输出 | 宽 / 高 | 宽高,Latent 已乘回 8 倍 |
搬运自 rgthree-comfy(
Image or Latent Size),MIT,保留原出处。一个上游带来的边界:遮罩和图像是靠张量维度区分的,所以批大小为 1、高度正好 1 像素的图像会被当成遮罩读(宽高对调)。实际几乎不会遇到,行为与上游一致, 没有改。
图像对比
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:搬运(
QG_ImageCompare)· ComfyUI-AusBoss(MIT)「Image Compare A/B 🆎」,只改类名 / 分类 / 显示名 / 中文文案
两个版本(改前 / 改后)的图放在一起看,不用来回开关节点。
- 滑动 —— 指针在画面上移动,竖线跟着走:左边露出 A,右边露出 B。A / B 两个小标签骑在竖线两侧
- 只看 A / 只看 B —— 点下面切换条上的
A或B,面板就锁在那一张 - 擦除 —— 一张图压在另一张上,画笔把上面那张擦掉一块,露出底下那张。
工具行里能改笔宽、软度、哪张在上面,
撤销/清空管笔迹:- 键盘:
[]改笔宽,Shift+[]改软度,E擦、B画回来,Ctrl+Z撤销、Esc取消正在画的这笔 - 鼠标:按住
Ctrl或鼠标右键,做当前工具的反面;Alt+ 右键拖动直接调笔 - 保存 —— 把混合图按原尺寸写进 ComfyUI 的 output 目录(不是把预览放大)。
勾上
PSD会另存一个双层 PSD(笔迹作上面那层的图层蒙版)和一张遮罩 PNG - 复制 —— 直接进剪贴板,粘到编辑器或聊天窗(只限 localhost / https 打开的页面)
- 键盘:
- 停在结果上 —— 指针离开画面后回到「结果」那张。哪一路算结果按连线判断:
B 默认是从 A 改出来的那张;如果 B 反过来喂给「做 A 的那张图」的来源,就改按 A 算。
设置里可以关掉(
QG-tools › 图像对比 › 停在结果上),关掉后就近吸到整张 - 原样透传 —— 输出就是输入 A 的整批图,所以节点可以夹在流程中间,下游照常跑
输入 / 输出
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 A / 图像 B | 两路 IMAGE,各取第一帧做预览 |
| 可选输入 | 文件名 | 接一根线进来给保存的文件起名(比如源图的文件名);目录和扩展名会被去掉。不接就用擦除行里打的名字 |
| 输出 | 图像 | 输入 A 原样送出 |
移植自 ComfyUI-AusBoss(图像对比 A/B),MIT,保留原出处。 笔迹存的是笔画而不是位图,所以保存时是按原图尺寸重画的,跟面板显示多大无关; 换了图(尺寸变了)旧笔迹会自动丢掉。
导出图像(JPEG / PNG / WEBP,画质就在保存这一步)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_ExportImage)
原生 SaveImage 只会写 PNG。社区的 JPG 保存节点大多把 quality 写死 90,让你在前面
串一个「压缩」节点 —— 那套不起作用:压缩节点交出去的是张量,保存节点会重新编码,
最终画质由保存节点说了算,前面那个旋钮只会白白毁一次图。
所以这里的画质旋钮就放在真正编码的那一步:
- 三种格式 ——
JPEG(有损,最小)/PNG(无损,最大)/WEBP(兼顾,支持透明) 质量只对 JPEG / WEBP 生效 —— PNG 是无损的,填了也不参与(压缩级别固定 4, 与原生 SaveImage 同档)色度采样只对 JPEG 生效 ——4:4:4保留全部彩色细节;4:2:2省约 15% 体积、 红橙边缘开始发软;4:2:0再省一些- 透明怎么处理 —— 合成白底 / 合成黑底 / 保留透明(PNG、WEBP 支持)。选 JPEG 时 「保留透明」会自动退化成白底,不会糊出一圈黑边
- 文件名与原生同形 ——
ComfyUI_00001_.jpg,五位数递增,扫描目录取最大值 +1, 所以和原生SaveImage往同一个文件夹存也不会互相覆盖 - 前缀能写模板 ——
%date:yyyyMMdd%/%time:HHmmss%里可以用yyyy yy MM dd HH hh mm ss;另有%INDEX%(批次内第几张)和%BATCH%(总数)。 原生那套%width% %height% %year% %month% %day% %hour% %minute% %second% %batch_num%也认,两套可以混着写 - 能存到任意目录 —— 留空写
output;填auto 图/2026就是 output 下的子目录; 也可填绝对路径、网络共享(\\NAS\共享\图)、环境变量(%USERPROFILE%\Desktop\图)或~\Desktop\图。系统目录、盘符根目录、只写一个盘符(D:)会被直接拒绝, 相对路径也不许跳出output - 自定义目录也有预览 —— ComfyUI 的
/view只服务output,所以另存一份最长边 1600 的缩略图到temp给节点显示,不为了预览再存一张全图 - 不会被缓存跳过 —— 保存节点每次都真的写盘,不会因为「输入没变」就不存
| 方向 | 名称 | 说明 |
|---|---|---|
| 输入 | 图像 | 图像批次,每张单独存一个文件 |
| 输入 | 格式 | JPEG / PNG / WEBP |
| 输入 | 质量 | 1–100,默认 90(只对 JPEG / WEBP) |
| 输入 | 色度采样 | 4:4:4 / 4:2:2 / 4:2:0(只对 JPEG) |
| 输入 | 透明处理 | 合成白底 / 合成黑底 / 保留透明 |
| 输入 | 文件名前缀 | 前缀 + 日期时间与序号模板 |
| 输入(可选) | 保存路径 | 目标目录,留空 = output |
| 输出 | — | 没有输出槽(终点节点) |
原创。只借了同类节点「画质旋钮该放在编码那一步」的结论,代码没搬。
画布标签 / Markdown 便签(画布上的自由文字)
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_CanvasLabel) 来源:原创(QG_MarkdownNote)
两个纯画布节点:不接线、不参与运行,丢在画布任何位置当标题、分组说明或备忘录。 都没有标题栏和边框,外观完全由节点自己绘制。
| | 画布标签 | Markdown 便签 | |---|---|---| | 内容 | 一行或多行纯文字 | Markdown(标题 / 粗斜体 / 列表 / 引用 / 表格 / 代码块 / 行内颜色) | | 编辑面板 | 贴着节点下方的浮动工具条,边改边在画布上实时生效 | 居中弹窗,左预览右表单;点「应用」之前只动预览,不写回画布 | | 取消 | 回滚到打开前的快照 | 直接丢弃,不碰节点 |
- 双击节点即可编辑;也可以右键 →
编辑标签…/编辑文本…。 - 能调的:字号、字体、颜色、背景色(含透明)、圆角、内边距、对齐、旋转角度,便签还能开关 Markdown 和自动折行。
- 尺寸跟着内容走,不用手拖;节点 Pin 住之后单击可以穿透选中下面的节点。
- 渲染器是自带的(纯 canvas 2D,不依赖浏览器 HTML、也没有外部库),所以导出图片不会被远程图片污染画布。
「工作流说明卡」是给别人看的卡片(大标题 + 使用说明 + 模型清单 + 依赖节点包 + 链接,还会对照本机标出缺什么), 这两个是给自己看的便签。用途不同,都留着。
采样预览
<!-- QG-ORIGIN:BEGIN --><!-- QG-ORIGIN:END -->来源:原创(
QG_StepPreview)
--preview-method 是启动参数:一旦写进启动器,服务器上每个工作流都跟着它,
要改只能重启 ComfyUI。于是要么全局关掉(想瞥一眼采样过程就得重启),
要么全局开着(不想预览的那条工作流也跟着拖慢)。
这个节点把开关按工作流给出来:丢在画布任意位置,不用连线,只有它所在的那份工作流 会显示采样中间步骤;跑完自动复位,别人的工作流、下一次排队都不受影响。
- 节点里直接看画面 —— 采样时画面就在这个节点里长出来,不用去盯 KSampler
- 第几步一目了然 —— 底部状态栏写着
step 7 / 20,跑完变成「完成」 - 能随时叫停 —— 底部有 STOP。出图跑偏时不必等它跑完,中断后画面留在节点上
- 三种预览方式 ——
快速(Latent2RGB 直接映射,不加载任何模型)/清晰(TAESD 解码,接近真实画面)/关闭 - 预览尺寸可调 —— 最大边长 64–2048,默认 512。远程连服务器时调到 256 能明显少传数据
- 不用连线 —— 丢在画布任意位置即可,它不在数据流里,只负责开开关
- 能从「全局已开」里关掉 —— 启动参数写了
auto、但这条工作流不想预览,把方式设成关闭即可。 关掉的是采样中间帧,不是成品图:跑完照样会显示预览图像/保存图像的成品 (成品图走 ComfyUI 的执行结果,跟采样预览没有关系) - 三个参数收在齿轮里 —— 预览方式 / 最大边长 / 隐藏缩略图不进节点版面, 点右下角 ⚙ 才展开,收起来时节点只有一块画面
- 缩略图只在面板里 —— 勾上「隐藏采样器缩略图」,画面就只在这个节点里出现, KSampler 上不再挂一张同样的小图。这是显示层的事,预览本身照旧在跑, 省不了服务器开销,只是把画布腾干净
三个参数都在右下角 ⚙ 里:
| 名称 | 说明 |
|---|---|
| 预览方式 | 自动 / 快速 / 清晰 / 关闭 |
| 最大边长 | 预览图的最大像素边长,只影响预览,不影响出图 |
| 隐藏采样器缩略图 | 勾上后采样器节点上不再显示缩略图,画面只在面板里 |
跑完之后如果有 预览图像 / 保存图像,节点里会换成成品图;没有的话保留最后一帧预览
(那是 Latent2RGB 的糊图,正常)。关闭 这一档没有中间帧,所以只有成品图——
工作流里一个 预览图像 / 保存图像 都没有时,节点跑完就是空的。
怎么生效的:新版 ComfyUI 在读 extra_data["preview_method"](PromptExecutor.execute_async
第一行就是 set_preview_method(...),传 None 则恢复启动默认)。本节点在排队之前由
PromptServer.add_on_prompt_handler 改写这个字段,一个字节的后端代码都没打补丁;
下个工作流不带这个节点,字段自然为空,ComfyUI 自己就复位了。
画面则是 ComfyUI 的采样器自己逐步骤发出来的,前端把那些帧接进节点里的画布; STOP 调的是 ComfyUI 自己的中断接口,和工具栏上那个「取消」是同一个。
老版本 ComfyUI 没有 extra_data 这个字段时,退化成节点执行时直接改全局设置 ——
只能影响它之后执行的采样器,精度差一点,但总比整台服务器重启强。
Nodes 2.0(Vue 渲染)
ComfyUI 新版可以把节点渲染成 Vue 组件(设置里的「Nodes 2.0 / Vue 渲染」)。
开启后画布不再调用节点自己的 onDrawForeground,所以把界面画在 canvas 上的节点会整块消失。
本包把这类节点全部迁到了 DOM,两种渲染模式下表现一致:
- 标注 / 便签:画布标签、Markdown 便签
- 数值 / 开关:数值、布尔开关、运行计时
- 图像:导出图像(含概要行与齿轮)
其余节点(各类加载器、显示任意、文本替换、加载文档、数学运算……)本来就以 DOM 卡片 或原生控件呈现,两种模式下一直在。
几个要点:
- 就地切换,不重载工作流 —— 改设置的那一刻,节点自己从旧容器搬到新外壳,位置、连线、 选中状态、正在编辑的文字全部保留;撤销栈也不会被清掉。
- 双击进入编辑(标签 / 便签类)—— Vue 模式下单击被用来拖节点,所以编辑改成双击, 阈值放宽到 750ms,手慢一点也算。
- 不出双影 —— Vue 模式下
draw()直接短路,画布上不重复画一遍。 - 尺寸按外壳换算 —— Vue 会额外加 30px 标题栏和最小宽度,插件按它算节点尺寸, 切换瞬间节点不会突然变宽变高。
QG 节点的外观
所有 QG 节点共用一个配色扩展:
- 新建节点时按当前配色方案自动上色,标题栏带一个
?徽章(点开是说明)。 - 右键任意 QG 节点 → QG 配色,可以单独改这一个节点,或者换整套配色方案。
- 已经手动挑过颜色的节点不会被自动覆盖 —— 想统一就点配色子菜单最后一项
「把所有 QG 节点重刷为当前配色」(选
Theme default即为清色)。
中文界面
切 ComfyUI 自己的界面语言就行:中文界面显示中文,英文界面显示英文,不用装汉化插件。
- 后端代码里写的是英文(节点标题、输入输出名、提示文字、下拉选项的值),中文来自插件
自带的
locales/zh/nodeDefs.json,ComfyUI 语言切到中文时自动叠上去。两边的对应关系 由tools/verify_bilingual.py双向体检:英文侧不许残留中文,中文侧不许漏条、不许 只是把英文抄一遍。 - 覆盖范围:节点标题、输入 / 输出名、每个输入的提示、右侧
?说明卡、下拉选项的显示名。 - 下拉选项的值是英文(
on-white这类),中文界面显示的是对应的中文译名(合成白底)。 存进工作流的是英文值,所以同一份工作流在两种界面下都能跑,也不会因为换界面而失效。 - 老工作流不用改:v0.9.4 之前的存档存的是中文选项值,打开时前端会就地换成英文值; 绕过前端(API 直连、脚本批量跑)也照样能执行,节点内部还会再兜一次。
- 装了 ComfyUI-Chinese-Translation 这类汉化插件时,本包还额外提供前端面板文案的汉化(按钮、菜单、状态提示)。
- 节点菜单里的分类名后端写英文(
QG-tools/Loaders、QG-tools/Mask),中文界面的 「加载器」「遮罩」来自插件自带的locales/zh/main.json里的nodeCategories—— 这是 ComfyUI 自己的分类翻译通道,跟节点标题一样,不用装汉化插件。 - 节点标题不带
QG前缀(分类仍在QG-tools下),所以标题栏干净、搜索框里也不会被一串同名前缀刷屏。
本文档里的节点名与选项名(
图像水印/合成白底/采用比例这类)都是 中文界面上看到的名称;英文界面下它们是等价的英文值,选项值形如on-white、from-preset(小写 + 短横线)。两种写法指的是同一个东西,老工作流里的中文值 会自动迁移,不用手改。
中英文搜索
节点标题跟着界面语言走(中文界面 图像水印、英文界面 Image Watermark),
中英文都能搜到:中文靠语言包里的译名,英文靠标题本身。除此之外每个节点还登记了一组
口语叫法(web/shared/node_aliases.mjs),页面加载时写进节点定义的 search_aliases,
ComfyUI 的搜索框会把它们和标题一起做模糊匹配。
中文名里带空格的节点(比如
空 Latent 分辨率)另登记了无空格写法: 敲空latent、空Latent、空latent分辨率都能搜到。 只按字面子串比的话,空 latent命中而空latent不命中,所以这层变体是必要的。
| 想找 | 可以搜 |
|---|---|
| 图像对比 | compare / image compare / ab compare / diff / before after |
| 图像水印 | watermark / logo / stamp |
| 图像裁剪 + 旋转 + 补边 | crop / rotate / pad / outpaint |
| 模型加载器 | triple loader / model loader / checkpoint / unet clip vae |
| 尺寸选择器 | size selector / aspect ratio / resolution |
| 空 Latent 分辨率 | 空latent / 空 latent / empty latent / megapixel / 百万像素 |
| 遮罩上色 / 拼接 | mask colorize / mask concat / merge masks |
想加词就改 web/shared/node_aliases.mjs 里对应节点那一行,刷新页面即可。
命中别名的节点会往前提一点,但最多 2 个。 这不是多余的设计:搜索框只取前 64 条,
而 text 这类词能命中 480 多个节点,QG 文本原本排第 159 名——等于搜不到。所以扩展会把
「别名里正好有这个词」的 QG 节点提到前面,最多提 2 个,其余保持原位。
搜 image 这种上位词时是 QG 图像缩放、QG 图像水印 排前两位,第 3 个就是原生节点;
搜 text 时是 QG 文本、QG 文本按分隔符分割 排前两位。不想看到这个行为的话,
把 web/shared/node_aliases.mjs 末尾那几个上位词(image / mask / size / model /
document / workflow / text)删掉即可,节点自己的英文名还会保留。
生效与排障
-
首次安装要完整重启 ComfyUI(不是刷新页面)。
-
之后前端有更新时,浏览器要
Ctrl+Shift+R强刷 —— ComfyUI 只在页面加载时读一次扩展列表。 (本插件的前端子模块都带版本串,正常情况下普通 F5 也能拿到新代码。) -
后端共 16 条路由(LoRA 6 条 + 文档 3 条 + Google 翻译 1 条 + 图像面板的视频预览 4 条 + 图像对比保存 1 条 + 版本探针 1 条),可用这条命令快速自检:
curl http://127.0.0.1:8188/qg/pack_version curl http://127.0.0.1:8188/qg/lora/list
许可证
本项目以 GPL-3.0-or-later 发布,全文见 LICENSE。
节点抽取来源:
39 个节点里 24 个搬运(改名 + 汉化 + 少量修上游 bug)、15 个原创 —— 其中 2 个是
参考上游思路自己重写、3 个来自作者自有旧插件,另外 10 个从零写。
口径:原创看代码是不是自己写的,搬运看是不是整段抄的 ——
参考过别人的思路但代码自己实现,仍记原创(参考对象照样写明);整段照抄上游、只改名字
和文案的才记搬运。
逐节点的文件级映射见 PORTED.json,权威清单见 ORIGINS.json。
要一份能单独分发的第三方声明(上游作者 / 许可证 / 贡献节点 / 修改摘要),见
THIRD-PARTY-NOTICES.md。
| 来源 | 许可证 | 贡献的节点 |
|---|---|---|
| ComfyUI-AusBoss | MIT | LoRA 加载器、图像裁剪 + 旋转 + 补边、工作流说明卡、工作流开关、运行计时器、图像对比(滑动 / A / B / 擦除 + 存混合图)、种子(卡片界面) |
| ComfyUI-Muye-nodes | MIT | 文本、图像水印、文字叠加图像、宫格图像拼接、遮罩上色、遮罩拼接、文本按分隔符分割、尺寸选择器 |
| ComfyUI_Comfyroll_CustomNodes | MIT | 文本替换、文本合并 |
| ComfyUI_Custom_Nodes_AlekPet | MIT | Google 翻译(上游依赖 googletrans,这里改用 requests 直连同一批端点) |
| rgthree-comfy | MIT | 图像缩放、图像或 Latent 尺寸、种子(取值逻辑) |
| 孤海工具箱(Goohaitools-comfyui) | GPL-3.0 | 任意切换、展示任意、路由阻断 |
| ComfyUI-Easy-Use | GPL-3.0 | 是否判断(未选中的一支懒执行) |
| ComfyUI-Crystools | GPL-3.0 | 字符串切换(只借思路,算原创:代码与文案全部重写) |
| comfyui-art-venture | MIT | 颜色校正(只借六个滑条的参数划分,算原创:纯 torch 重写) |
| 作者自有旧插件(ComfyUI-MD-Reader / ComfyUI-TripleLoader / ComfyUI-EmptyLatentResolution) | 本项目 | 加载文档、模型加载器、空 Latent 分辨率(本来就是自己写的,算原创) |
| 原创(无上游代码) | 本项目 | 布尔开关、数值、数值滑条、数学运算、存在判断、颜色匹配、画布标签、Markdown 便签、导出图像 |
MIT 来源的原许可证全文保留在 licenses/;GPL-3.0 来源与本项目同许可证,
按 GPL 要求在各节点章节末尾保留出处标注。被改写部分的原始版权仍归原作者所有。
MIT 与 GPLv3 兼容,因此整体以 GPLv3 分发是合规的。
作者自己写的部分(三合一模型加载器、加载文档、空 Latent 分辨率、字符串切换、颜色校正、颜色匹配,以及上面那 9 个 无上游代码的节点)版权归作者,同样以 GPL-3.0-or-later 发布。