Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理、文本处理、AI 模型集成和遮罩处理等多种功能。
custom_nodes 目录中pip install -r requirements.txt分类: Rui-Node🐶/图像调节🎨
功能描述:
调整图像的色彩饱和度,可以创建黑白图像或增强色彩鲜艳度。
输入参数:
image (IMAGE): 输入图像saturation (FLOAT): 饱和度调整系数
1.0 = 增加饱和度
输出:
IMAGE: 调整后的图像使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
对图像进行水平或垂直翻转操作。
输入参数:
image (IMAGE): 输入图像flip_direction (选择): 翻转方向
输出:
IMAGE: 翻转后的图像使用场景:
分类: Rui-Node🐶/文件存储与加载📁
功能描述:
从指定的文件路径加载图像文件,支持绝对路径输入。
输入参数:
image_path (STRING): 图像文件的完整路径
输出:
IMAGE: 加载的图像特殊处理:
使用场景:
分类: Rui-Node🐶/AI模型🤖
功能描述:
使用阿里云千问(Qwen)编辑模型 API 进行 AI 图像生成,支持多种控制模式。
输入参数:
image1 ~ image4 (IMAGE): 最多 4 张输入图像作为参考api_key (STRING): 阿里云 API 密钥base_url (STRING): API 基础 URL
seed (INT): 随机种子
control_mode (选择): 控制模式
width (INT): 输出图像宽度
height (INT): 输出图像高度
输出:
IMAGE: AI 生成的图像使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
将包含多个分镜描述的脚本文本拆分成独立的分镜列表,支持按范围筛选导出。
输入参数:
input_text (STRING): 输入的多分镜描述脚本(多行文本)
<SHOT_XXX>...</SHOT_XXX> 标签包裹每个分镜start_shot_num (INT, 可选): 开始导出的分镜编号
shot_count (INT, 可选): 导出的分镜数量
输出:
shot_descriptions (LIST): 拆分后的分镜描述列表summary (STRING): 总结信息文本格式示例:
<SHOT_1>
第一个镜头的描述内容
</SHOT_1>
<SHOT_2>
第二个镜头的描述内容
</SHOT_2>
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
从分镜描述文本中自动提取旁白/对白内容。
输入参数:
input_text (STRING): 输入的分镜描述文本(多行文本)输出:
dialogues (LIST): 提取的旁白/对白列表summary (STRING): 总结信息识别模式:
旁白:[对白内容]旁白:对白内容<SHOT_XXX> 标签中的旁白使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
删除文本中所有以"页面旁白:"或"页面旁白:"开头的整行内容。
输入参数:
input_text (STRING): 原始文本(多行文本)输出:
clean_text (STRING): 移除页面旁白行后的文本处理规则:
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
将多个独立的文本段落组织成列表形式输出。
输入参数:
text1 (STRING, 必需): 第一段文本(多行文本)text2 ~ text5 (STRING, 可选): 第 2~5 段文本(多行文本)输出:
text_list (LIST): 文本列表(Python 列表格式)summary (STRING): 总结信息处理规则:
使用场景:
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
对输入的多个遮罩进行排序并选择特定遮罩,同时输出剩余遮罩的合并结果。
输入参数:
masks (MASK): 输入的遮罩(可包含多个遮罩)sort_method (选择): 排序方法
index (INT): 选择的遮罩编号(1-based 索引)
输出:
选中遮罩 / Selected (MASK): 选中的单个遮罩剩余遮罩 / Remaining (MASK): 其他遮罩的合并结果信息 / Info (STRING): JSON 格式的详细信息
total_masks: 遮罩总数selected_index: 选中编号sort_method: 排序方式selected_area: 选中遮罩的像素面积selected_center: 选中遮罩的质心坐标 [x, y]index_clamped: 编号是否越界被修正使用场景:
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
将遮罩以半透明彩色形式叠加显示在图像上,方便直观查看遮罩覆盖区域。节点自带预览功能,同时输出合成后的图像。
输入参数:
image (IMAGE): 作为底图的原始图像mask (MASK): 需要可视化的遮罩mask_color (选择): 遮罩显示颜色
opacity (FLOAT, 可选): 不透明度
输出:
图像 / Image (IMAGE): 合成了半透明彩色遮罩的图像特性:
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
删除输入字符串中所有非 UTF-8 编码字符(如孤立的代理对),确保输出的字符串符合 UTF-8 编码规范。
输入参数:
input_text (STRING): 需要处理的原始字符串(支持多行)输出:
filtered_text (STRING): 过滤后的符合 UTF-8 规范的字符串log (STRING): 处理日志,包含移除字符的详细信息和统计总结使用场景:
分类: Rui-Node🐶/AI模型🤖
功能描述:
连接 OpenAI 或兼容 API(如 DeepSeek、Moonshot 等),进行文本生成或多模态图像理解,支持最多 6 张图像同时输入。
输入参数:
api_url (STRING): API 接口地址
api_key (STRING): API 密钥model (STRING): 模型名称
system_prompt (STRING): 系统提示词user_prompt (STRING): 用户提示词seed (INT): 随机种子,用于控制生成的随机性image_1 ~ image_6 (IMAGE, 可选): 最多 6 张输入图像
temperature (FLOAT, 可选): 采样温度
max_tokens (INT, 可选): 最大输出 token 数
detail (选择, 可选): 图像分析细节等级
image_max_size (INT, 可选): 单张图像最长边缩放上限
proxy_url (STRING, 可选): HTTP/HTTPS 代理地址
http://127.0.0.1:7890输出:
text (STRING): 模型生成的文本内容使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
将目标图像的颜色分布匹配到参考图像的颜色分布,支持多种匹配算法和混合调节。
输入参数:
reference_image (IMAGE): 作为颜色参考的图像moving_image (IMAGE): 需要改变颜色的目标图像match_method (选择): 匹配算法
blend_factor (FLOAT): 混合系数
输出:
颜色匹配后图像 (IMAGE): 颜色调整后的图像匹配信息 (STRING): 记录了使用的匹配方式以及混合系数的日志信息使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
从白色/浅色背景的合图(Sprite Sheet)中自动拆分出每个独立的美术元素,通过连通区域检测进行裁剪,并将每个独立元素作为图像列表输出。
输入参数:
图像 (IMAGE): 输入的带有透明通道的合图图像(RGBA格式)最小面积过滤(像素数) (INT): 最小面积过滤
裁剪边距 (INT): 裁剪边距
排序方式 (选择): 排序方式
seed (INT): 随机种子
输出:
图像列表 (IMAGE): 拆分后的多张图像列表,透明区域会用白色填充输出。使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
与标准素材拆分节点功能相同,但保留并额外输出 Alpha 透明通道,适用于需要透明背景的美术素材提取。
输入参数:
输出:
图像列表 (IMAGE): 拆分后的多张 RGB 图像列表遮罩列表 (MASK): 对应的多张 Alpha 透明通道遮罩列表,1.0代表不透明,0.0代表透明使用场景:
JoinImageWithAlpha 等节点生成透明 PNG 图像分类: Rui-Node🐶/文件存储与加载📁
功能描述:
基础功能与 ComfyUI 原生的 "Load Image" 节点完全一致,支持从 ComfyUI 的 input 目录中选择图像,并支持拖拽上传。区别在于本节点额外提供了一个字符串输出端口,用于输出图像的文件名。
输入参数:
image (下拉选择): 从 input 目录中选择图像文件,或通过按钮上传输出:
IMAGE: 图像数据MASK: 图像的 Alpha 通道遮罩filename (STRING): 图像的文件名(不包含后缀,例如上传了 test_image.png,则输出 test_image)使用场景:
主要依赖库包括:
torch: PyTorch 深度学习框架numpy: 数值计算Pillow (PIL): 图像处理requests: HTTP 请求(用于 API 调用)完整依赖请查看 requirements.txt
基于 SDMatte(vivo 相机研究院,ICCV 2025)的交互式抠图节点。 擅长发丝、绒毛、玻璃、烟雾等常规抠图模型处理不好的边缘。
包含两个节点:
| 节点 | 作用 |
|---|---|
| SDMatte 加载器 | 载入权重,构建网络并常驻显存 |
| SDMatte 精细抠图 | 用视觉提示(框/掩码/点)驱动模型输出 alpha |
把权重放到 ComfyUI/models/SDMatte/ 下即可,两种格式任选其一:
SDMatte_plus.pth — 官方发布,12.1GB,LongfeiHuang/SDMatteSDMatte_plus.safetensors — 社区转换,5.19GB,1038lab/SDMatte这两个文件的模型权重逐比特完全相同,不必纠结选哪个。 已实测比对全部 1316 个张量:键名、形状、精度(均为 F32)、数值全部一致,无一例外。 官方 pth 是 detectron2 的训练检查点,顶层为
{"model", "trainer", "iteration"}, 多出的约 6.9GB 是trainer里的优化器状态与梯度缩放器,推理不参与。 换用 pth 不会带来任何质量提升。本节点两种格式都支持,读 pth 时只解析model段, 内存占用与 safetensors 相当。
不需要下载 Stable Diffusion 2.1 的权重。 SDMatte 虽以 SD 2.1 为骨架,但官方推理配置
(configs/SDMatte.py 中 load_weight=False)只用配置文件搭出网络结构,全部权重随后由
SDMatte 检查点覆盖。官方 HuggingFace 仓库本身也只发布 .pth 加若干 config.json,
不含任何 SD 权重。所需配置已随本节点一起分发,开箱即用、无需联网。
SDMatte 加载器
| 参数 | 说明 |
|---|---|
ckpt_name | models/SDMatte/ 下的权重文件 |
precision | fp32(默认,与官方测试配置一致)/ fp16(省显存,但 SD 2.1 的 VAE 半精度下易溢出) |
device | auto / cpu |
attention_slicing | 默认开启。1024 下显存峰值从约 15.5GB 降到 9.1GB,实测速度反而略快,输出差异仅 1e-6 量级 |
显存参考(fp32 @ 1024,实测于 RTX 5090):开分片约 9.1GB,关分片约 15.5GB。 12GB 显存的卡请保持分片开启。
SDMatte 精细抠图
| 参数 | 说明 |
|---|---|
mask | 指示抠哪个目标的提示掩码,不必精确,粗略覆盖主体即可 |
prompt_type | 视觉提示类型,见下表 |
inference_size | 默认 1024,与官方测试一致 |
is_transparent | 玻璃、纱、烟雾等透明物体务必打开 |
caption | 目标物体的英文描述。仅 SDMatte.pth 有效,SDMatte_plus.pth 请留空,见下文 |
point_radius | 仅 point_mask 生效。每个点晕开的高斯 sigma,默认 35 |
seed | 仅 point_mask 生效(10 个点是随机取的) |
prompt_type 选择:
| 取值 | 含义 | 适用 |
|---|---|---|
bbox_mask | 取掩码外接框作为提示 | 默认,官方测试脚本的主路径,通常最稳 |
mask | 直接用掩码本身 | 已有较准的粗分割时 |
point_mask | 在掩码内随机取 10 个点 | 仅 SDMatte.pth 支持,见下文 |
auto_mask | 不给定位信息 | 画面只有单一主体 |
官方 README 里,SDMatte 与 SDMatte*(即 SDMatte_plus)的训练集不同:
前者含 RefMatte(指代表达式抠图数据集,点提示与文本提示的来源),
后者用 COCO-Matte 替换了它。这导致 plus 版不具备点提示与文本指代能力:
SDMatte.pth | SDMatte_plus.pth | |
|---|---|---|
bbox_mask / mask / auto_mask | ✅ | ✅ |
point_mask | ✅ MAD 0.0135 | ❌ 输出全黑(max 仅 0.079) |
caption 语义 | ✅ 填对小幅提升 | ❌ 无作用,填了反而更差 |
caption 实测(羊驼图,MAD 越低越好):
| caption | SDMatte | SDMatte_plus |
|---|---|---|
""(留空) | 0.01120 | 0.01135 ← 最好 |
"alpaca"(语义正确) | 0.01072 ← 最好 | 0.01160 ← 最差 |
"tree"(语义错误) | 0.01111 | 0.01119 |
在 SDMatte 上,语义正确的描述确实更准;在 plus 上语义完全失效甚至反向,
说明它只是给 cross-attention 注入了噪声扰动,并非在理解文本。
结论:用 SDMatte_plus.pth 时保持 caption 留空、prompt_type 用 bbox_mask;
想用点提示或文本指代,请换 SDMatte.pth。节点在 point_mask 输出接近全黑时会打印警告。
加载图像 ──────────────┬──> SDMatte 精细抠图 ──> alpha (MASK)
│ ▲ └──> cutout (IMAGE)
任意分割节点 ──> mask ──┘ │
SDMatte 加载器 ───────────────────┘
mask 可以来自任何粗分割来源(SAM、rembg、手绘遮罩皆可)——SDMatte 的职责正是把粗糙边缘细化。
用官方效果图中的羊驼原图(绒毛边缘)跑本节点,与官方给出的 GT alpha 对比:
| 指标 | 数值 |
|---|---|
| MAD(平均绝对误差) | 0.0113 |
| MSE | 0.0026 |
| SAD | 0.807 千像素 |
(GT 取自官方效果图截图,含有损压缩与水印,故存在固有误差下限。)
各配置对输出的实际影响(透明玻璃杯,差异像素指偏差 > 0.05 的占比):
| 对照项 | 平均差 | 差异像素占比 |
|---|---|---|
inference_size 1024 vs 512 | 0.082 | 32.4% |
is_transparent 关 vs 开 | 0.059 | 25.0% |
官方 [F,T,F] vs 误用 [T,T,T] 条件分配 | 0.026 | 18.8% |
结论:分辨率影响最大,建议保持 1024;抠透明物体时 is_transparent 必须打开。
同一张图、同一份权重、同一台机器,对跑 ComfyUI-SDMatte 与本节点,以官方公布的 alpha 为参照:
| 实现 | 配置 | MAD ↓ |
|---|---|---|
| 本节点 | 官方 configs/SDMatte.py,bbox 提示,fp32 | 0.0113 |
| ComfyUI-SDMatte | 默认(trimap 提示 + mask_refine) | 0.0884 |
| ComfyUI-SDMatte | 关闭 mask_refine | 0.0885 |
相差 7.8 倍,且其输出肉眼可见地发灰、边缘晕开。
主因是视觉提示类型:官方 configs/SDMatte.py 固定 aux_input="bbox_mask",
而其 aux_input_list 只含 point_mask / bbox_mask / mask —— trimap 从未作为视觉提示参与训练。
ComfyUI-SDMatte 传 aux_input="trimap",把模型推到了没训练过的输入模式上,
且该分支的 trimap_coords 恒为 [0,0,1,1],定位信息全部丢失。
开不开它的 mask_refine 几乎不影响这一结论(0.0884 vs 0.0885),说明问题不在后处理。
若与其它 SDMatte 实现效果对不上,按影响从大到小排查:
视觉提示类型(影响最大)。必须用官方训练过的 bbox_mask / mask / point_mask,
并传入真实的归一化坐标。用 trimap 当视觉提示是模型没见过的用法。
UNet 配置来源。SDMatte 在标准 SD 2.1 的 UNet 配置上额外定义了
bbox_time_embed_dim / point_embeddings_input_dim / bbox_embeddings_input_dim 三个字段。
误用原版 SD 2.1 的 config.json 会缺这些字段,只能猜默认值,猜错则相应权重被
strict=False 静默丢弃。本节点直接分发官方配置,并在缺字段时直接报错而非猜测。
transformers 版本。官方权重用 transformers 4.x 保存,CLIPTextModel 内部裹了一层
text_model;transformers 5.x 起该层被移除,导致 text_encoder 的 372 个权重键名对不上、
被整体静默丢弃、停留在随机初始化。本节点会按当前环境自动增删该前缀。
条件分配。官方 use_encoder_hidden_states_list=[False, True, False] 决定 UNet
下采样/中间/上采样三段各接收哪种条件,漏传会退化成 [True, True, True]。
实测单独影响不大(羊驼 MAD 0.01135 → 0.01148),透明物体上更明显。
权重对齐校验。本节点在加载后校验键的完整性,一旦有权重未被覆盖或未被使用就中止并报错。 这类问题不会让模型崩溃,只会让输出质量悄悄下降,是最难排查的一类,因此宁可停下也不放行。
全程 fp32、1024 分辨率,且不做任何启发式后处理(不做阈值裁剪、对比度拉伸之类的"优化"), 输出即模型原始 alpha。
分类: Rui-Node🐶/AI模型🤖
功能描述:
连接 ZenMux 聚合平台(OpenAI 兼容协议),一个节点即可调用其收录的所有文本类模型(Anthropic、OpenAI、Google、DeepSeek、Qwen 等 20 家厂商、130+ 模型)。支持文本生成与多模态图像理解(最多 6 张图)。
特色功能:
价格直接标在选项上: 每个模型后缀形如 [入$0.2/M 出$1.25/M],即输入/输出每百万 token 的美元价格,选型时一目了然
快速筛选: 模型列表按「厂商/模型名」排序聚类,同厂商模型天然相邻;在下拉的搜索框输入厂商前缀(如 qwen/、anthropic/)即可只看该厂商的模型
离线可用的模型清单: 模型与价格来自随包分发的 zenmux/models_snapshot.json;价格有变动时运行 python zenmux/build_snapshot.py 即可重新拉取更新
旧工作流兼容: 价格快照更新后,旧工作流里保存的带旧价格标签仍能正确解析出模型 id,不会失效
单次消耗统计: usage_stats 输出本次运行的 token 用量、输出字数与费用换算(按快照单价计算,汇率可调),格式:
token消耗,输入:1234,输出:567
输出文字数量:328
模型类型:openai/gpt-5.4-nano [入$0.2/M 出$1.25/M]
价格换算,美元:0.000955,人民币:0.006876
自动参数兼容: 部分模型弃用或不支持某些采样参数(如 claude-sonnet-5 弃用 temperature、gpt-5 reasoning 系要求 max_completion_tokens)。节点会在收到相关 400 错误时自动剔除或改名该参数并重试,无需手动调整;剔除动作会打印到 ComfyUI 控制台。正常请求不受影响、无额外开销。
输入参数:
api_key (STRING): ZenMux 平台的 API Key(在 zenmux.ai 控制台获取)model (选择): 模型(带价格标注),默认 openai/gpt-5.4-nanosystem_prompt (STRING): 系统提示词user_prompt (STRING): 用户提示词seed (INT): 随机种子temperature (FLOAT, 可选): 采样温度,默认 0.7,范围 0.0 ~ 2.0top_p (FLOAT, 可选): 核采样阈值,默认 1.0max_tokens (INT, 可选): 最大输出 token 数,默认 1024image_1 ~ image_6 (IMAGE, 可选): 多模态图像输入(所选模型需支持 image 输入)detail (选择, 可选): 图像分析细节等级,auto/low/highimage_max_size (INT, 可选): 发送前图像最长边缩放上限,默认 1024base_url (STRING, 可选): API 地址,默认 zenmux.ai/api/v1(无需写 https://,节点会自动补全)proxy_url (STRING, 可选): HTTP/HTTPS 代理地址,如 127.0.0.1:7890usd_to_cny (FLOAT, 可选): 美元兑人民币汇率,默认 7.2,用于 usage_stats 的人民币换算,可按当日牌价调整输出:
text (STRING): 模型生成的文本内容model_id (STRING): 实际调用的模型 id(如 openai/gpt-5.4-nano),便于下游记录usage_stats (STRING): 单次运行的 token 消耗、输出文字数量(按字符计,含标点)与费用统计(四行文本,格式见上);请求失败时记为 0 消耗,token 数缺失或单价未知的项显示 ?使用场景:
网络自动重连:
线上跑批时最常见的失败不是参数错,而是链路抖动 —— 典型报错是
SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol')),
即 TLS 握手/传输被中途打断。这类失败重连一次往往就好了,因此节点内置了重连机制。
| 参数 | 默认 | 说明 |
|---|---|---|
max_retries | 3 | 网络失败后的自动重连次数,0 = 不重连 |
timeout | 180 | 单次请求超时秒数,超时计入重连次数 |
会重连:SSL 握手被打断(SSLEOFError)、连接被重置、连接/读超时、
响应体传到一半截断(ChunkedEncodingError / JSON 解析失败),
以及 429 限流与 5xx 服务端临时故障。
不重连:参数类 400、鉴权类 401/403、404 —— 这些重试多少次都是同样结果,
重连只会拖慢报错。
退避策略:1s → 2s → 4s → 8s → 16s 指数增长,每次叠加 ±25% 随机抖动。
抖动不是可有可无的装饰 —— 一条工作流里常有多个 API 节点同时失败,没有抖动它们会在
同一毫秒一起重连,把刚缓过来的服务端再打垮一次。服务端返回 Retry-After 头时以它为准。
与「自适应参数重试」的关系:两者是不同层次,互不消耗额度。参数自适应处理的是 「这个模型不认这个参数」(HTTP 400),网络重连处理的是「没拿到完整响应」。 参数被剔除后的 payload 会在后续重连中保留,不会重蹈覆辙。
重连过程会打印到控制台,例如:
[Rui-Node] 越光: 连接失败(SSLError),1.1s 后重连(第 1/3 次)
[Rui-Node] 越光: 第 2 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
分类: Rui-Node🐶/文本处理📝
功能描述:
输入 Markdown 文本,输出按阅读器级排版渲染的图片(IMAGE)。视觉规范对标 GitHub / Typora:标题层级字号(2.0/1.5/1.25/1.0/0.875/0.85 倍正文)、H1/H2 底部分隔线、引用左竖条、代码块圆角底色 + 等宽字体 + 语言标签、表格圆角外框 + 表头加粗底色 + 斑马纹 + 列对齐、任务清单勾选框、彩色 Emoji。纯 PIL 实现,无额外依赖。
支持的 Markdown 语法:
标题 #~######、段落(单换行即硬换行)、粗体、斜体、行内代码、删除线、链接、有序/无序/嵌套列表、任务清单 - [x]、引用 >(可嵌套)、围栏代码块、表格(:---: 对齐语法)、分割线 ---;表格与正文中的 Emoji 以系统彩色字体渲染。
输入参数:
markdown (STRING): Markdown 文本size_preset (选择): 常用尺寸快选(1080×1440 / 1080×1920 / 1080×1080 / 1920×1080 / A4 等),选 custom 时使用下方宽高width / height (INT): 精确尺寸(64~8192px,custom 时生效)font (选择): 字体,列表来自 Ruinode/font 目录(ttf/otf/ttc 均可,放入后刷新页面即出现在下拉;同族粗体文件如 msyhbd 会自动配对用于渲染粗体,无粗体文件时描边模拟)theme (选择): 浅色 / 深色 / 米色三套阅读器配色body_size、h1_size ~ h6_size (STRING, 可选): 各级字号,auto(默认)按输出尺寸二分搜索「恰好优雅填满画布」的字号,各级也可分别填数字精确指定letter_spacing (STRING, 可选): 字间距像素,默认 autoline_spacing (STRING, 可选): 行高倍数(如 1.8),默认 auto(正文 1.65)max_chars_per_line (STRING, 可选): 单行文字字数上限,达到即换行;默认 auto(按像素宽自然换行)输出:
image (IMAGE): 渲染结果,固定为所选宽高;内容超高时按现有字号裁剪并在控制台提示使用场景:
⚠️ 重要:不要用 WAS 的「Text Multiline」节点喂 Markdown
WAS Node Suite 的「Text Multiline」会把 # 开头的行当注释删除,标题行会凭空消失,还会做动态提示词替换。请改用本套件的 多行文本框(原样输出),或直接在本节点的 markdown 输入框里粘贴文本。
分类: Rui-Node🐶/文本处理📝
功能描述:
把输入的多行文本一字不动输出为 STRING:不删注释行、不做动态提示词/通配符/token 替换。专门用来安全承载 Markdown、代码等格式敏感文本(WAS 的「Text Multiline」会把 # 开头的行当注释吃掉,喂 Markdown 时标题会消失)。
输入参数:
text (STRING): 多行文本输出:
text (STRING): 与输入完全一致的文本使用场景:
# 标题的原样文本分类: Rui-Node🐶/图像调节🎨
功能描述:
给输入图像铺满一层平铺的文字水印,常用于版权标注、样图防盗、批量打标。文字按交错网格平铺,整体旋转后从中心裁切与原图等大的区域,因此任意旋转角度下四角也都被水印覆盖,不留空白。支持中英文混排与多行文案(用换行分隔),逐字符绘制以支持字间距。批量图像逐张处理。
输入参数:
image (IMAGE): 输入图像text (STRING, 多行): 水印文案,支持换行分隔的多行文本font (选择): 字体,列表来自 Ruinode/font 目录(ttf/otf/ttc,放入后刷新页面即出现,与 Markdown 节点共用同一套字体扫描)font_size (INT): 文字大小(像素),默认 48,范围 8~500angle (FLOAT): 水印整体旋转角度(度),默认 30,范围 -180~180density (FLOAT): 水印密度,综合控制行间距与同行水印之间的间距,值越大越密,默认 1.0,范围 0.1~5.0letter_spacing (INT): 字间距,单条文案内相邻字符的额外间距(像素,可为负),默认 0,范围 -20~200opacity (FLOAT): 水印透明程度,0=完全透明(原样返回),100=完全不透明,默认 35,范围 0~100color (STRING): 水印文字颜色,支持 #RRGGBB / #RGB / "r,g,b" / 常见英文色名(white、red、yellow…),默认 #FFFFFF输出:
image (IMAGE): 叠加水印后的图像使用场景:
分类: Rui-Node🐶/抠图✂️
功能描述:
全自动去背景抠图,不需要任何提示,输入图像直接输出 alpha。模型为 feyn 开源的 FeyNobg(Apache-2.0),在 BiRefNet(CAAI AIR 2024)基础上扩展:Swin-Large 主干 + 梯度注意力 / 图像块注入 / 多尺度输入三项增强,原生 1024×1024 推理,权重约 1.05GB。
与 SDMatte 精细抠图 的分工:
模型准备:
首次运行会自动从 HuggingFace 下载到 ComfyUI/models/nobg/FeyNobg(约 1.05GB)。也可手动下载 config.json、preprocessor_config.json、model.safetensors 放入该目录。
输入参数:
image (IMAGE): 输入图像model_name (选择): models/nobg 下的模型目录,未找到时自动下载resolution (选择): 推理分辨率,默认 1024(模型原生训练分辨率)。调低省显存但边缘变粗;调高不一定更好,可能出现结构断裂precision (选择): fp32(默认)/ fp16。实测两者输出一致(同图 alpha 均值均为 0.657),fp16 显存减半且明显更快,推荐优先用 fp16device (选择): auto / cpualpha_threshold (FLOAT, 可选): 前景判定阈值,默认 0.5。见下方「主体半透明发灰怎么救」alpha_softness (FLOAT, 可选): 阈值两侧过渡带宽度,默认 1.0 = 完全不处理keep_aspect_ratio (BOOLEAN, 可选): 保持宽高比(等比缩放 + 边缘延展补边),默认关闭invert_mask (BOOLEAN, 可选): 反转 alpha,默认前景为白输出:
alpha (MASK): 抠图 alpha,值域 [0,1]cutout (IMAGE): 去背景图(黑底)。需要透明 PNG 时,把 alpha 接到 JoinImageWithAlpha 一类节点实测数据(1139×1280 人物插画,RTX 显卡):
| 配置 | 耗时 | 前景占比 |
|---|---|---|
| fp32 @1024 | 12.4s(含首次加载) | 0.659 |
| fp16 @1024 | 2.4s | 0.659 |
| fp32 @768 | 2.2s | 0.656 |
发丝、飘带、细链条等高频细节均能完整分离,边缘为自然的半透明过渡而非硬边。
主体「整片半透明发灰」怎么救:
模型对拿不准的区域会输出 0.5 上下的中间值,表现为整个人物/物体呈半透明。模型本身没有开放任何控制该行为的参数(use_gradient_attention 等是训练时固化的架构参数,推理期不可调),因此节点在后处理层提供了一对色阶参数:
| alpha_threshold | alpha_softness | 效果 |
|---|---|---|
| 0.5 | 1.0 | 默认,原样输出,一个像素都不动 |
| 0.35 | 0.3 | 推荐,半透明像素占比 1.49% → 0.31%(降 79%),主体均值几乎不变 |
| 0.5 | 0.0 | 硬二值化,锯齿硬边,抠头发/玻璃慎用 |
原理是以 threshold 为中心、softness 为宽度取一段区间线性拉伸到 [0,1]:区间以下压成全透明,以上提成全不透明,区间内保留平滑过渡。默认参数下该区间恰好是 [0,1],等于恒等变换。
两点边界必须说明:
softness 越小,发丝等真实半透明细节损失越多,是一对权衡。长图形变:模型固定吃 1024×1024,默认把图直接拉伸成正方形(与官方训练方式一致)。手机截图这类 1:2 以上的长图横向会被压到一半,可开 keep_aspect_ratio 改为等比缩放 + 边缘延展补边、推理后裁掉补边。实测 2.36:1 的图半透明占比 0.1192 → 0.1041。该选项与训练分布不同,属试验性,常规比例建议保持关闭。
实现说明(两个坑,都已在节点内处理):
预处理依赖:上游 nobg 的预处理模块继承 transformers>=5.4 的 TorchvisionBackend,而 ComfyUI 常见环境仍是 transformers 4.x,直接引入会报 No module named 'transformers.image_processing_backends'。本节点内嵌了 nobg 推理子集(feynobg/)并重写了预处理,数值规格与官方逐项对齐(1024 双线性抗锯齿缩放 + ImageNet 标准化;后处理先 sigmoid 再缩放),无需升级 transformers。同时绕开了上游 AutoModel 里会联网查 tags 的 model_info(),保证离线可用。
权重键名不兼容(更隐蔽):FeyNobg 的权重用 transformers 5.x 导出,其 SwinBackbone 的模块命名与 4.x 不同(bb.swin.* 多一层、attention 从 self.query/key/value 重构为 q/k/v_proj、前馈层 mlp.fc1/fc2 对应 intermediate.dense/output.dense)。若不处理,958 个参数只有 405 个能对上,整个 backbone 形同随机初始化——模型照样跑完不报错,但输出的 alpha 几乎全黑(实测 max 0.02、mean 0.000)。节点内做了键名重映射(按环境自动判断是否需要),并严格校验:除确定性 buffer relative_position_index 与 backbone 末端未使用的 bb.layernorm 外,任何缺失/多余都直接报错中止,绝不接受静默劣化的结果。
分类: Rui-Node🐶/抠图✂️
功能描述:
全自动去背景,不需要任何提示。模型为 Lucida(MIT),是 BiRefNet_HR 的微调版,训练目标是攻克多数开源抠图模型的短板:伪装物体、透明材质(玻璃)、文字与 Logo、VFX 光效、插画。权重约 885MB(220M 参数,Swin-Large 主干)。
作者在 203 图 9 类别基准上的 MAE(越低越好):
| 类别 | Lucida | 商业参考 |
|---|---|---|
| 文字 / Logo 保留 | 0.0091 | 0.0123 |
| 插画 | 0.0092 | — |
| 伪装物体 | 0.0270 | — |
| 印刷设计 / 贴纸 | 0.0235 | — |
| 总体 | 0.0257 | — |
模型准备:
首次运行自动下载到 ComfyUI/models/lucida/lucida.safetensors。也可手动下载仓库的 model.safetensors,改名为 lucida.safetensors 放入该目录。
输入参数:
image (IMAGE): 输入图像model_name (选择): models/lucida 下的权重文件,未找到时自动下载precision (选择): fp16(默认)/ fp32device (选择): auto / cpualpha_threshold / alpha_softness (FLOAT, 可选): 遮罩色阶,默认 (0.5, 1.0) 为恒等变换。用法同 FeyNobg 节点keep_aspect_ratio (BOOLEAN, 可选): 保持宽高比,默认关闭invert_mask (BOOLEAN, 可选): 反转 alpha输出:
alpha (MASK) / cutout (IMAGE,黑底)⚠ 没有分辨率选项:模型内部 Config.size=1024 且 decoder 走 patch split,与 1024 输入绑定,因此不像 FeyNobg 那样可调分辨率。
三个抠图节点怎么选:
| 节点 | 特点 | 适用 |
|---|---|---|
| Lucida | 全自动,把半透明材质也算前景 | 文字/Logo、插画、玻璃、发光特效、伪装物体 |
| FeyNobg | 全自动,只找主要主体 | 常规主体照片,要求背景剥离干净 |
| SDMatte | 需框/掩码提示 | 画面里多个主体、只抠其中一个 |
实测对比(同图、同参数,本仓库两个全自动节点):
| 测试图 | Lucida 前景占比 | FeyNobg 前景占比 |
|---|---|---|
| 动漫插画(人物 + 云 + 栏杆) | 0.391 | 0.098 |
| 游戏场景图 | 0.395 | 0.378 |
| 人物插画 | 0.315 | 0.336 |
第一张图差异最大,肉眼核对后确认不是精度高低,而是「前景」的定义不同:FeyNobg 只抠出人物,云与栏杆全部排除;Lucida 除人物外还把半透明的云判为前景(灰度 alpha)并保留了栏杆——这与它专门训练透明材质的目标一致。所以两者是互补关系:要干净剥离主体用 FeyNobg,要保住文字/玻璃/光效等半透明元素用 Lucida。建议在自己的素材上实测再定,示例工作流已把两者并联便于对照。
⚠ alpha_softness 调小会把玻璃、发光这类真实半透明一并压实,而这正是 Lucida 的强项,务必按素材取舍。
实现说明:
模型代码(birefnet.py / BiRefNet_config.py,2250 行)内嵌在 lucida/ 子包,不使用 trust_remote_code——那会在运行时从 HuggingFace 拉取并执行远程 Python 代码,ComfyUI 场景下既不该联网也不该执行随时可变的远程代码;内嵌后版本固定、可离线、可审计。构造时传 bb_pretrained=False,避免联网下载 Swin 的 ImageNet 预训练权重。预处理规格与 BiRefNet 系一致,直接复用 FeyNobg 节点那份已验证实现。权重加载同样做严格校验(除窗口尺寸推出的确定性 buffer 外,任何失配直接报错中止)。
分类: Rui-Node🐶/图像调节🎨
功能描述:
把普通图像转成能直接当素材用的像素画。与"马赛克滤镜"的区别在于:滤镜只是把画面涂成方块、输出仍是原尺寸大图;而像素游戏要的是真实小分辨率、颜色数受控、边缘硬朗的 sprite。纯 numpy/PIL 实现,无额外依赖、无需模型权重。
三种模式:
| 模式 | 用途 |
|---|---|
| 按目标宽度 | 普通图/照片/插画 → 像素画,给输出宽度即可(高度按比例自动算) |
| 按像素块大小 | 每 N×N 原像素合成一个像素,已知放大倍数时最精确 |
| 自动检测网格 | 探测图中隐含的像素网格并还原——专治 AI 生成的伪像素图 |
第三种是重点:SD/Flux 生成的"像素风"图往往是 1024×1024,看着像素风,实际网格歪斜、边缘带抗锯齿、颜色成千上万,直接进引擎会糊。
输入参数:
image (IMAGE) / mask (MASK, 可选): 接抠图节点的 alpha 会按同一网格降采样并二值化成硬边mode / target_width / pixel_size: 见上表downsample (选择): 主导色 dominant(默认,取块内最多的颜色,不会凭空造出新颜色)/ median / mean(会糊边) / centerpalette (选择): 不量化 / 自适应 k-means(CIELAB 空间聚类)/ 自适应 median cut / PICO-8 (16色) / Game Boy (4色绿) / 黑白 1-bit / 灰阶 4·8·16 级palette_size (INT): 自适应调色板的颜色数。8dither (选择): 无 / Bayer 2×2·4×4·8×8 / Floyd-Steinberg / 随机噪声output_scale (INT): 1 = 真实像素尺寸(导出素材必须用 1);>1 仅为在 ComfyUI 里看清,放大是整数倍纯复制不插值dither_strength / mask_threshold / seed (可选)输出: image (IMAGE) / mask (MASK) / info (STRING,含检测到的网格与置信度)
方案选型(研究后的结论):
Pixel Snapper(Sprite Fusion,MIT)解决的是「伪像素图 → 完美像素图」,思路是检测网格 + 按主导色重采样;而「普通图 → 像素画」是另一个问题,核心在降采样方式与调色板量化。本节点把两条路做进同一节点,算法为自研实现。网格检测按公开研究的要点处理了两类经典误判:
评分用单元内方差而非相邻像素差分:差分对模糊极敏感,而 AI 伪像素图的边界都带抗锯齿,尖峰被摊平后压不住内容周期(开发中实测:4 像素的网格被判成 24~28)。改用组内方差后,过大的 s 会因单元跨越多个真实色块导致方差爆掉而被天然压制。
实测数据:
| 测试项 | 结果 |
|---|---|
| 干净放大图(k=2~16,各 3 组) | 27/27 全对,零八度错误 |
| 退化图(模糊+噪点,模拟 AI 伪像素图) | 10/15 |
| 非方形网格(9×6)、相位偏移 (3,5) | 全部正确 |
| 普通插画(无网格) | 正确判定为"未检出" |
| 端到端还原(32×32 放大 10 倍 + 模糊噪点) | 还原回 32×32,与真值 MAE 0.0049 |
| 完美像素校验(8× 放大抽样 == 1× 输出) | True(整数倍纯复制,无插值) |
⚠ 自动检测对干净放大图几乎必中,对模糊严重的图约 2/3 命中率。info 输出会给出检测到的网格与置信度,结果不对时改用「按像素块大小」手动指定即可。
分类: Rui-Node🐶/图像调节🎨
功能描述:
用于 8 方向行走动画 制作管线:把每帧都排布着 8 个朝向的雪碧图序列,一次拆成 8 条各自独立、可直接成片的动画序列,并完成方向编号与分组。
完整管线与分工:
| 步骤 | 由谁完成 |
|---|---|
| 角色图 → 八方向静态图 | GPTimage2 / Holopix Universal Edit 等 |
| 静态图 → 循环行走视频 | Seedance 首尾帧等 |
| 视频 → 序列帧 | 从文件读用 VHS「Load Video」;接在视频生成节点后面用原生「Get Video Components」 |
| 抽帧(降帧率) | VHS「Select Every Nth Image」 |
| 抠图(提供语义级 alpha) | Lucida / BiRefNet 等 |
| 拆分 + 编号 + 分组 + 8 队列输出 | 本节点 |
| 8 组透明 PNG 序列帧 | SaveImage(4 通道输入会自动存成 RGBA) |
| 8 个透明 webm | VHS「Video Combine」,format=video/webm + pix_fmt=yuva420p |
整条链路只有拆分环节是缺失的,其余全部复用成熟实现。
两个示例工作流:
一体化工作流的关键是打通 VIDEO → IMAGE:视频生成节点输出的是 ComfyUI 的 VIDEO 类型,而 VHS「Load Video」只能从文件读、接不上。用 ComfyUI 原生的「Get Video Components」(image/video 分类)即可,输入 VIDEO、输出 images/audio/fps,不需要装任何额外插件。
⚠️ 帧率两处必须匹配:Seedance 出的是 24fps,抽帧间隔与输出帧率要对应,否则 webm 播放速度不对。
select_every_nth=3 ↔ frame_rate=8;要 12fps 就用 2 ↔ 12;要全量 24fps 就用 1 ↔ 24。
输入参数:
images (IMAGE): 视频转出的序列帧masks (MASK, 可选): 上游抠图节点的遮罩,强烈建议接上(见下方「透明通道怎么来」)grid_cols / grid_rows / empty_cells: 网格布局。3×3 中间留空即 empty_cells=4(序号行优先、从 0 开始)direction_names (STRING): 按「跳过空格后的先后顺序」命名,默认 SW,S,SE,W,E,NW,N,NE,对应行 1 面向观众、行 3 背对观众的排布bg_mode / bg_threshold: 透明通道来源,见下edge_shrink / decontaminate: 治白边,见下fragment_threshold (FLOAT): 清掉面积不足主体这一比例的连通碎片expand_beyond_cell (BOOLEAN): 务必开启,允许角色超出格子边界auto_crop / crop_padding: 按内容裁剪透明通道怎么来(关系到成品质量,别用默认凑合):
| bg_mode | 原理 | 代价 |
|---|---|---|
| 已带透明通道(默认推荐) | 用上游 Lucida / FeyNobg 的语义级 alpha | 需要跑模型 |
| 白底转透明 | 纯颜色阈值 + 边缘连通性 | 角色身上的白衣服会被啃出破洞 |
| 不处理 | 输出不透明(仍按角色范围裁剪不切断) | — |
颜色阈值法的死穴在于它按「离白色多远」估 alpha,白衬衫本身就接近白、alpha 天生偏低,一旦收边压白边,衬衫就被啃穿。实测同一素材、同等白边水平下:
| 方案 | 白边强度 | 主体被啃面积 |
|---|---|---|
| 颜色阈值法(收边 0.35) | 0.0261 | 0.0373 |
| Lucida alpha(收边 0.2) | 0.0256 | 0.0242(少 35%) |
Lucida 一次就能识别整张雪碧图的全部 8 个角色(各格前景占比 0.18~0.24,中间空格 0.002),肉眼比对:模型 alpha 的白衬衫完好,阈值法的衬衫上布满背景色斑块。
治白边的两个参数:
edge_shrink(主力):把边缘那圈「几乎全是背景」的半透明像素收掉。白底素材的边缘像素本就掺了白,不收掉贴到深色背景就发白。实测白边强度:0 → 0.048;0.2 → 0.026;0.5 → 0.016。配模型 alpha 用 0.15~0.25,配阈值法要 0.35 以上decontaminate(辅助):颜色反溢出,按 观察色 = 前景×a + 白×(1-a) 反解真正的前景色。单独用只改善约 3%(因为观察色本身已经太白,反解出来还是白),必须和收边配合输出: dir_1 ~ dir_8 (IMAGE,4 通道 RGBA) + info (STRING)
锚点对齐:让 8 个方向尺寸统一、切换朝向不跳
做游戏素材时这一步是刚需。不开对齐时,每个方向各按自己的内容裁剪,8 个方向出 8 种尺寸,角色在各自画面里的位置也不一致——游戏里切换朝向角色就会跳一下。人工做法是「一帧一帧手动对位置」,本节点把它自动化了:
| 参数 | 说明 |
|---|---|
align_mode | 锚点对齐·统一画布(默认)/不对齐 |
anchor_type | 脚底中心(默认)/包围盒底边中心/包围盒中心 |
align_scope | 逐帧对齐·脚底钉死(默认)/按方向统一平移 |
为什么锚点取「脚底中心」而不是包围盒中心:角色站在地面上,脚底才是它在世界里的位置;而斗篷、披风、手杖会把包围盒拽向一侧。所以 y 取最低的不透明行,x 取底部窄带的水平质心——那些外挂物基本不会垂到脚底,走路时两脚一前一后,窄带质心正好落在两脚之间,也就是人真正站立的点。
实测(97 帧真实素材):
| 输出尺寸 | 各方向锚点散布 | 同方向跨帧位移 | |
|---|---|---|---|
| 不对齐 | 8 种各不相同 | x 48.9px / y 27px | — |
| 按方向统一平移 | 统一 267×372 | x 7.1px / y 4px | 13~23px(保留摆动) |
| 逐帧对齐(默认) | 统一 284×367 | x 0.76px / y 0px | ~1px |
默认选逐帧对齐,是因为行走循环本就该原地播放、位移交给游戏代码,sprite 内部不该有整体漂移;而 AI 生成的视频往往有(实测同方向跨帧漂移达 22px)。角色本就该有前后摆动的动作(挥剑、跳跃)则改用「按方向统一平移」。
info 输出会给出统一画布尺寸、锚点坐标、以及 Unity/Godot 的归一化 pivot(左下为原点),例如:
统一画布 267×372,锚点(脚底中心)位于 (144.5, 346.0)
Unity/Godot 归一化 pivot(左下为原点):(0.5411, 0.0699)
把那个 pivot 填进引擎的 Sprite 设置,8 个方向就能共用同一套坐标。
三个关键设计:
用固定网格而非连通区域拆分(本仓库的素材拆分节点)。连通区域按包围盒排序,角色走动时位置浮动,一旦跨过排序行界方向就会错乱——上百帧里错一帧整条动画就废了;且每个 sprite 按各自 bbox 裁剪、尺寸不一,无法合成视频。固定网格没有这两个问题。(连通区域拆分依然更适合单张静态合图,两者各有用途。)
白底转透明用边缘连通性判断。角色常穿白衣服,按亮度阈值一刀切会把白衬衫一起掏空。这里只把与画面边缘相连的白色判为背景,被角色包围的白色一律保留。
裁剪框取全序列并集。逐帧各自裁剪会导致尺寸不一且角色在帧间跳动;取并集则整条序列尺寸一致、位置连贯。
实测(97 帧 834×1112 的真实素材):
| 项目 | 结果 |
|---|---|
| 拆分耗时 | 约 4 秒,8 方向 × 97 帧 |
| 输出尺寸 | 150×335 ~ 206×326,方向内完全一致 |
| 方向稳定性 | 跨帧内容重心极差 0.5~12 px(走路摆动的正常范围,无跳变) |
| 碎片清理效果 | E 方向 172×370 → 150×335,重心极差 8.0 → 0.5 px |
| webm 透明 | 导出后回读透明像素占比 0.635,与素材一致 |
⚠️ 验证 webm 透明时容易被误导:alpha 存放在 WebM 的独立边带里,ffprobe 看主流会显示 yuv420p,用 ffmpeg 默认解码回读也会得到全不透明——这是内置 vp9 解码器不处理 alpha 边带所致,并非文件丢了透明。需显式加 -c:v libvpx-vp9 解码才能读到。播放器与 Unity/Godot 走的是 libvpx,能正确读取。
分类: Rui-Node🐶/AI模型🤖
功能描述:
通过越光(Nebula)聚合平台调用其收录的文本类模型。OpenAI 兼容协议,chat 端点 https://llm.ai-nebula.com/v1/chat/completions。参数、输出与容错行为与 ZenMux 节点 保持一致,便于两者互换。
模型清单(25 个,价格单位 USD / 百万 token):
| 厂商 | 模型 | 输入 | 输出 |
|---|---|---|---|
| OpenAI | gpt-5.6-sol | 4.75 | 5.00 |
| gpt-5.6-terra | 2.375 | 2.50 | |
| gpt-5.6-luna | 0.95 | 1.00 | |
| gpt-4.1 / gpt-4.1-mini | 2.00 / 0.40 | 8.00 / 1.60 | |
| gpt-4o / gpt-4o-mini | 2.50 / 0.15 | 10.00 / 0.60 | |
| o4-mini / o3-mini | 1.10 | 4.40 | |
| Anthropic | claude-opus-5 | 5.00 | 5.00 |
| claude-opus-4-7 / 4-6 | 15.00 | 75.00 | |
| claude-sonnet-5 | 2.00 | 2.00 | |
| claude-sonnet-4-6 | 3.00 | 15.00 | |
| claude-haiku-4-5-20251001 | 0.80 | 4.00 | |
| claude-fable-5 | 3.00 | 15.00 | |
| DeepSeek | deepseek-v4-pro | 2.19 | 8.76 |
| deepseek-v4-flash(默认) | 0.10 | 0.30 | |
| deepseek-r1-250528 | 0.55 | 2.19 | |
| deepseek-v3-250324 | 0.27 | 1.10 | |
| Kimi | kimi-k3 | 2.86 | 2.86 |
| kimi-k2.7-code / k2.6 / k2.5 / k2-thinking | 1.00 | 4.00 |
输入参数: 与 ZenMux 节点相同——api_key、model(下拉带价签)、system_prompt、user_prompt、seed,以及可选的 temperature、top_p、max_tokens、image_1~image_6、detail、image_max_size、base_url、proxy_url、usd_to_cny。
输出: text / model_id / usage_stats(五行:token 消耗、输出字数、厂商、模型与单价、美元与人民币费用)
与 ZenMux 节点的三点差异:
yueguang/model_registry.py 里——少一个联网环节,也不会因拉取失败导致下拉变空。价格变动时改那张表即可。gpt-4o 而非 openai/gpt-4o)。下拉里同厂商靠排序聚在一起,搜索时输 gpt / claude / deepseek / kimi 过滤。deepseek-v4-flash($0.10/$0.30),官方示例也用它,默认值便宜可避免误触发时产生意外费用。沿用的实战经验:
base_url 默认值不带 ://——ComfyUI 前端会吞掉文本框里的协议片段(本仓库为此修过多次),协议由后端自动补全temperature、或要求用 max_completion_tokens 取代 max_tokens,命中这类 400 时会剔除/改名后自动重试,正常请求零额外开销VALIDATE_INPUTS 宽松放行:价格表更新后旧工作流里保存的标签不再逐字匹配,但只要能解析出 model id 就放行,不会让整个工作流失效网络自动重连:
线上跑批时最常见的失败不是参数错,而是链路抖动 —— 典型报错是
SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol')),
即 TLS 握手/传输被中途打断。这类失败重连一次往往就好了,因此节点内置了重连机制。
| 参数 | 默认 | 说明 |
|---|---|---|
max_retries | 3 | 网络失败后的自动重连次数,0 = 不重连 |
timeout | 180 | 单次请求超时秒数,超时计入重连次数 |
会重连:SSL 握手被打断(SSLEOFError)、连接被重置、连接/读超时、
响应体传到一半截断(ChunkedEncodingError / JSON 解析失败),
以及 429 限流与 5xx 服务端临时故障。
不重连:参数类 400、鉴权类 401/403、404 —— 这些重试多少次都是同样结果,
重连只会拖慢报错。
退避策略:1s → 2s → 4s → 8s → 16s 指数增长,每次叠加 ±25% 随机抖动。
抖动不是可有可无的装饰 —— 一条工作流里常有多个 API 节点同时失败,没有抖动它们会在
同一毫秒一起重连,把刚缓过来的服务端再打垮一次。服务端返回 Retry-After 头时以它为准。
与「自适应参数重试」的关系:两者是不同层次,互不消耗额度。参数自适应处理的是 「这个模型不认这个参数」(HTTP 400),网络重连处理的是「没拿到完整响应」。 参数被剔除后的 payload 会在后续重连中保留,不会重蹈覆辙。
重连过程会打印到控制台,例如:
[Rui-Node] 越光: 连接失败(SSLError),1.1s 后重连(第 1/3 次)
[Rui-Node] 越光: 第 2 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
分类: Rui-Node🐶/抠图✂️
功能描述:
纯数学去底,等效 After Effects 的 Unmult。纯色背景上的合成图满足 C = αF + (1-α)B,背景色 B 已知时可反解出前景色 F 与透明度 α。不需要模型推理,速度快、结果是精确解,且能真实保留半透明层次——这是语义抠图模型给不了的。
输入参数:
image (IMAGE): 待去底图像,支持批量(序列帧/视频帧逐帧处理)bg_color (STRING): 要去除的背景色,#RRGGBB。常用 #000000 / #FFFFFF / #00FF00 / #FF00FF黑点 (FLOAT, 滑块): 低于此值的 alpha 归零,用于清除背景残留噪点。调太高会丢边缘细节白点 (FLOAT, 滑块): 高于此值的 alpha 归一,用于让主体更实。调太低会让边缘硬化主体保护 (BOOLEAN): 是否采纳 subject_mask。关闭时即便已连线也完全不采纳,等同纯 Unmult——想对比「有无 AI 介入」时拨这个开关即可,不必拔线subject_mask (MASK, 可选): 接抠图节点输出的 alpha,节点执行 max(unmult_α, subject_mask) 合并后两项用中文参数名 + display: slider,界面上就是两条滑块,与 LayerStyle 的 BiRefNet Ultra 观感一致。函数内部用 **kwargs 接收(中文名不能直接做函数形参),并兼容旧的 alpha_low/alpha_high 调用。
输出: rgba_image (IMAGE,4 通道) / alpha (MASK)
实测(构造已知合成图反推,验证还原精度):
| 场景 | alpha 平均误差 | 前景色平均误差 |
|---|---|---|
| 发光素材 @ 黑底 | 0.0000 | 0.0000 |
| 发光素材 @ 白底 | 0.0000 | 0.0000 |
| 发光素材 @ 绿幕 | 0.0000 | 0.0000 |
数学上是精确解,三种底色都能完美还原。
⚠ 适用边界与破解办法:
| 素材 | 纯 Unmult | 接 subject_mask 后 |
|---|---|---|
| 光效、火焰、烟雾、粒子、UI 特效 | ✅ 最佳选择,半透明层次完整保留 | 一般不需要 |
| 绿幕/品红等与素材反差大的底色 | ✅ 实体素材也能扣干净 | 一般不需要 |
| 黑底 + 暗色实体 | ❌ 暗部会被当成背景扣掉 | ✅ 已解决 |
实测同一个实体素材(alpha 真值恒为 1,下半部分接近纯黑):
| 条件 | 暗部还原 alpha |
|---|---|
| 黑底,不接 mask | 0.080 ← 黑头发、深色衣服、鞋子被扣穿 |
| 黑底,接 mask 且「主体保护」启用 | 1.000 ✅ |
| 黑底,接 mask 但「主体保护」关闭 | 0.080(与不接完全一致,开关确实生效) |
| 绿幕,不接 mask | 0.940 ✓ 本来就正常 |
根因是黑底 unmult 本质在用"亮度当不透明度",这对发光物成立、对实体不成立。破法是接一路语义抠图(Lucida / FeyNobg / BiRefNet)的 alpha 进 subject_mask:主体区域强制不透明,主体之外仍走 Unmult 的精确半透明。两者各取所长——语义模型负责"哪里是主体",Unmult 负责"边缘有多透"。
四个抠图节点怎么选:
| 节点 | 原理 | 适用 |
|---|---|---|
| Unmult | 纯数学反解 | 纯色底的光效/火焰/粒子;绿幕素材 |
| Lucida | 语义模型 | 文字/Logo、插画、玻璃、伪装物体 |
| FeyNobg | 语义模型 | 常规主体照片,要求背景剥离干净 |
| SDMatte | 语义模型 + 提示 | 画面里多个主体、只抠其中一个 |
Rui-Node🐶 致力于为 ComfyUI 用户提供实用、高效的节点工具集。🐶 是我们的项目标志,代表着忠诚、友好和可靠。
分类: Rui-Node🐶/视频🎬
功能描述: 从带透明通道的视频中解出 RGBA 序列帧,alpha 不丢失。用来解决一个很常见、 但排查起来相当隐蔽的问题:带 alpha 的 WebM 用常规加载视频节点读进来,透明通道没了。
为什么会丢——根因:
带 alpha 的 WebM(VP8/VP9)并不把透明度放在主视频流里。主流仍然是 yuv420p,
alpha 被单独压成第二路,藏在 Matroska 的 BlockAdditional 边带中,容器上只留
一条 alpha_mode=1 的元数据作记号。
ffmpeg 内置的 vp9 / vp8 解码器根本不读这条边带,只有 libvpx-vp9 / libvpx
才会。VideoHelperSuite 等常见加载节点走的是默认解码器,于是拿到的每一帧 alpha 恒为 255。
实测同一个文件的三条路径:
| 解码路径 | alpha 结果 |
|---|---|
PyAV 默认(解码器 vp9) | 全 255,丢失 |
| ffmpeg 默认 | 全 255,丢失 |
显式 -c:v libvpx-vp9 | min=0 max=255,全透明 87.2%、半透明 2.0%,完整 |
本节点显式指定 libvpx 解码器,并以 rgba 原始像素流读回,因此连半透明边缘也一并保留。 对 MOV/qtrle、ProRes 4444 等本身带 alpha 通道的格式同样适用。
输入参数:
video: 从 input 目录选择视频文件强制帧率 (FLOAT): 按指定帧率重采样,0=保持原始帧率帧数上限 (INT): 最多读取多少帧,0=读完整段(达到上限立即中止解码)跳过前N帧 (INT): 丢弃开头若干帧间隔 (INT): 每隔几帧取一帧,1=每帧都要自定义宽度 / 自定义高度 (INT): 0=保持原始;只填一边时另一边按比例换算解码器: 自动(探测到 alpha_mode=1 的 VP8/VP9 时自动换 libvpx)/ 强制 libvpx(保 alpha) / 默认解码器视频路径 (STRING, 可选): 绝对路径,填写后优先于下拉选择输出:
rgba_image (IMAGE): 4 通道 RGBA 序列帧alpha (MASK): 透明通道rgb_image (IMAGE): 3 通道,供只吃 3 通道的下游节点使用帧数 (INT) / 帧率 (FLOAT)存成带透明通道的 PNG 序列帧:
rgba_image 直接接 ComfyUI 原生「保存图像」节点即可。原生节点的像素处理是
Image.fromarray(...),4 通道数组会被识别成 RGBA 模式,存出的 PNG 完整保留 alpha——
不需要额外的保存节点。实测 33 帧全部为 RGBA 模式,与内存中的 alpha 逐像素零误差。
关于预览发黑:
ComfyUI 的预览区不渲染透明,看到黑底是正常现象,不代表 alpha 丢了。
判断是否成功以 alpha 输出接遮罩预览为准,或直接看存出的 PNG 文件。
示例工作流: example_workflow/透明视频转PNG序列帧.json
关于节点内视频预览被裁切:
如果节点下方的视频预览只显示画面的一部分(按原始像素尺寸渲染、超出部分被切掉),
根因不在本节点,而是 comfyui-art-venture 插件的一处全局 CSS 误伤。
它在 web/upload.js 里为自家的 LoadVideoFromUrl 注入了这条规则:
.comfy-img-preview video {
width: var(--comfy-img-preview-width);
height: var(--comfy-img-preview-height);
}
选择器是全局的,会盖掉 ComfyUI 官方的 width:100%; height:100%;而这两个 CSS 变量
只在 art-venture 自家节点的 DOM 上定义,其它节点上取到空值 —— 变量为空时整条声明失效,
<video> 退回固有尺寸(例如 640×640)撑破容器,容器 overflow:hidden 于是把画面裁掉。
本仓库通过前端扩展 web/rui_video_preview_fit.js 修正,注入两条规则:
.comfy-img-preview.rui-video-fit video 强制 100% + object-fit:contain,
容器标记由拦截 node.videoContainer 赋值时打上,必定生效100% 的回退值 —— 变量有值时行为完全不变
(art-venture 自己的节点不受影响),仅在变量为空这种本就失效的情况下恢复官方行为实测(640×640 视频、347px 宽容器):修复前 video 渲染为 640×640 溢出被裁; 修复后为 347×347 完整显示。
该修复随
WEB_DIRECTORY加载,需要重启 ComfyUI 后端并刷新浏览器才会生效。
本项目遵循开源协议,欢迎使用和贡献。
Happy Creating with Rui-Node🐶! 🎨✨
50 commits
Python
99.3%
Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理、文本处理、AI 模型集成和遮罩处理等多种功能。
custom_nodes 目录中pip install -r requirements.txt分类: Rui-Node🐶/图像调节🎨
功能描述:
调整图像的色彩饱和度,可以创建黑白图像或增强色彩鲜艳度。
输入参数:
image (IMAGE): 输入图像saturation (FLOAT): 饱和度调整系数
1.0 = 增加饱和度
输出:
IMAGE: 调整后的图像使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
对图像进行水平或垂直翻转操作。
输入参数:
image (IMAGE): 输入图像flip_direction (选择): 翻转方向
输出:
IMAGE: 翻转后的图像使用场景:
分类: Rui-Node🐶/文件存储与加载📁
功能描述:
从指定的文件路径加载图像文件,支持绝对路径输入。
输入参数:
image_path (STRING): 图像文件的完整路径
输出:
IMAGE: 加载的图像特殊处理:
使用场景:
分类: Rui-Node🐶/AI模型🤖
功能描述:
使用阿里云千问(Qwen)编辑模型 API 进行 AI 图像生成,支持多种控制模式。
输入参数:
image1 ~ image4 (IMAGE): 最多 4 张输入图像作为参考api_key (STRING): 阿里云 API 密钥base_url (STRING): API 基础 URL
seed (INT): 随机种子
control_mode (选择): 控制模式
width (INT): 输出图像宽度
height (INT): 输出图像高度
输出:
IMAGE: AI 生成的图像使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
将包含多个分镜描述的脚本文本拆分成独立的分镜列表,支持按范围筛选导出。
输入参数:
input_text (STRING): 输入的多分镜描述脚本(多行文本)
<SHOT_XXX>...</SHOT_XXX> 标签包裹每个分镜start_shot_num (INT, 可选): 开始导出的分镜编号
shot_count (INT, 可选): 导出的分镜数量
输出:
shot_descriptions (LIST): 拆分后的分镜描述列表summary (STRING): 总结信息文本格式示例:
<SHOT_1>
第一个镜头的描述内容
</SHOT_1>
<SHOT_2>
第二个镜头的描述内容
</SHOT_2>
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
从分镜描述文本中自动提取旁白/对白内容。
输入参数:
input_text (STRING): 输入的分镜描述文本(多行文本)输出:
dialogues (LIST): 提取的旁白/对白列表summary (STRING): 总结信息识别模式:
旁白:[对白内容]旁白:对白内容<SHOT_XXX> 标签中的旁白使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
删除文本中所有以"页面旁白:"或"页面旁白:"开头的整行内容。
输入参数:
input_text (STRING): 原始文本(多行文本)输出:
clean_text (STRING): 移除页面旁白行后的文本处理规则:
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
将多个独立的文本段落组织成列表形式输出。
输入参数:
text1 (STRING, 必需): 第一段文本(多行文本)text2 ~ text5 (STRING, 可选): 第 2~5 段文本(多行文本)输出:
text_list (LIST): 文本列表(Python 列表格式)summary (STRING): 总结信息处理规则:
使用场景:
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
对输入的多个遮罩进行排序并选择特定遮罩,同时输出剩余遮罩的合并结果。
输入参数:
masks (MASK): 输入的遮罩(可包含多个遮罩)sort_method (选择): 排序方法
index (INT): 选择的遮罩编号(1-based 索引)
输出:
选中遮罩 / Selected (MASK): 选中的单个遮罩剩余遮罩 / Remaining (MASK): 其他遮罩的合并结果信息 / Info (STRING): JSON 格式的详细信息
total_masks: 遮罩总数selected_index: 选中编号sort_method: 排序方式selected_area: 选中遮罩的像素面积selected_center: 选中遮罩的质心坐标 [x, y]index_clamped: 编号是否越界被修正使用场景:
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
将遮罩以半透明彩色形式叠加显示在图像上,方便直观查看遮罩覆盖区域。节点自带预览功能,同时输出合成后的图像。
输入参数:
image (IMAGE): 作为底图的原始图像mask (MASK): 需要可视化的遮罩mask_color (选择): 遮罩显示颜色
opacity (FLOAT, 可选): 不透明度
输出:
图像 / Image (IMAGE): 合成了半透明彩色遮罩的图像特性:
使用场景:
分类: Rui-Node🐶/文本处理📝
功能描述:
删除输入字符串中所有非 UTF-8 编码字符(如孤立的代理对),确保输出的字符串符合 UTF-8 编码规范。
输入参数:
input_text (STRING): 需要处理的原始字符串(支持多行)输出:
filtered_text (STRING): 过滤后的符合 UTF-8 规范的字符串log (STRING): 处理日志,包含移除字符的详细信息和统计总结使用场景:
分类: Rui-Node🐶/AI模型🤖
功能描述:
连接 OpenAI 或兼容 API(如 DeepSeek、Moonshot 等),进行文本生成或多模态图像理解,支持最多 6 张图像同时输入。
输入参数:
api_url (STRING): API 接口地址
api_key (STRING): API 密钥model (STRING): 模型名称
system_prompt (STRING): 系统提示词user_prompt (STRING): 用户提示词seed (INT): 随机种子,用于控制生成的随机性image_1 ~ image_6 (IMAGE, 可选): 最多 6 张输入图像
temperature (FLOAT, 可选): 采样温度
max_tokens (INT, 可选): 最大输出 token 数
detail (选择, 可选): 图像分析细节等级
image_max_size (INT, 可选): 单张图像最长边缩放上限
proxy_url (STRING, 可选): HTTP/HTTPS 代理地址
http://127.0.0.1:7890输出:
text (STRING): 模型生成的文本内容使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
将目标图像的颜色分布匹配到参考图像的颜色分布,支持多种匹配算法和混合调节。
输入参数:
reference_image (IMAGE): 作为颜色参考的图像moving_image (IMAGE): 需要改变颜色的目标图像match_method (选择): 匹配算法
blend_factor (FLOAT): 混合系数
输出:
颜色匹配后图像 (IMAGE): 颜色调整后的图像匹配信息 (STRING): 记录了使用的匹配方式以及混合系数的日志信息使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
从白色/浅色背景的合图(Sprite Sheet)中自动拆分出每个独立的美术元素,通过连通区域检测进行裁剪,并将每个独立元素作为图像列表输出。
输入参数:
图像 (IMAGE): 输入的带有透明通道的合图图像(RGBA格式)最小面积过滤(像素数) (INT): 最小面积过滤
裁剪边距 (INT): 裁剪边距
排序方式 (选择): 排序方式
seed (INT): 随机种子
输出:
图像列表 (IMAGE): 拆分后的多张图像列表,透明区域会用白色填充输出。使用场景:
分类: Rui-Node🐶/图像调节🎨
功能描述:
与标准素材拆分节点功能相同,但保留并额外输出 Alpha 透明通道,适用于需要透明背景的美术素材提取。
输入参数:
输出:
图像列表 (IMAGE): 拆分后的多张 RGB 图像列表遮罩列表 (MASK): 对应的多张 Alpha 透明通道遮罩列表,1.0代表不透明,0.0代表透明使用场景:
JoinImageWithAlpha 等节点生成透明 PNG 图像分类: Rui-Node🐶/文件存储与加载📁
功能描述:
基础功能与 ComfyUI 原生的 "Load Image" 节点完全一致,支持从 ComfyUI 的 input 目录中选择图像,并支持拖拽上传。区别在于本节点额外提供了一个字符串输出端口,用于输出图像的文件名。
输入参数:
image (下拉选择): 从 input 目录中选择图像文件,或通过按钮上传输出:
IMAGE: 图像数据MASK: 图像的 Alpha 通道遮罩filename (STRING): 图像的文件名(不包含后缀,例如上传了 test_image.png,则输出 test_image)使用场景:
主要依赖库包括:
torch: PyTorch 深度学习框架numpy: 数值计算Pillow (PIL): 图像处理requests: HTTP 请求(用于 API 调用)完整依赖请查看 requirements.txt
基于 SDMatte(vivo 相机研究院,ICCV 2025)的交互式抠图节点。 擅长发丝、绒毛、玻璃、烟雾等常规抠图模型处理不好的边缘。
包含两个节点:
| 节点 | 作用 |
|---|---|
| SDMatte 加载器 | 载入权重,构建网络并常驻显存 |
| SDMatte 精细抠图 | 用视觉提示(框/掩码/点)驱动模型输出 alpha |
把权重放到 ComfyUI/models/SDMatte/ 下即可,两种格式任选其一:
SDMatte_plus.pth — 官方发布,12.1GB,LongfeiHuang/SDMatteSDMatte_plus.safetensors — 社区转换,5.19GB,1038lab/SDMatte这两个文件的模型权重逐比特完全相同,不必纠结选哪个。 已实测比对全部 1316 个张量:键名、形状、精度(均为 F32)、数值全部一致,无一例外。 官方 pth 是 detectron2 的训练检查点,顶层为
{"model", "trainer", "iteration"}, 多出的约 6.9GB 是trainer里的优化器状态与梯度缩放器,推理不参与。 换用 pth 不会带来任何质量提升。本节点两种格式都支持,读 pth 时只解析model段, 内存占用与 safetensors 相当。
不需要下载 Stable Diffusion 2.1 的权重。 SDMatte 虽以 SD 2.1 为骨架,但官方推理配置
(configs/SDMatte.py 中 load_weight=False)只用配置文件搭出网络结构,全部权重随后由
SDMatte 检查点覆盖。官方 HuggingFace 仓库本身也只发布 .pth 加若干 config.json,
不含任何 SD 权重。所需配置已随本节点一起分发,开箱即用、无需联网。
SDMatte 加载器
| 参数 | 说明 |
|---|---|
ckpt_name | models/SDMatte/ 下的权重文件 |
precision | fp32(默认,与官方测试配置一致)/ fp16(省显存,但 SD 2.1 的 VAE 半精度下易溢出) |
device | auto / cpu |
attention_slicing | 默认开启。1024 下显存峰值从约 15.5GB 降到 9.1GB,实测速度反而略快,输出差异仅 1e-6 量级 |
显存参考(fp32 @ 1024,实测于 RTX 5090):开分片约 9.1GB,关分片约 15.5GB。 12GB 显存的卡请保持分片开启。
SDMatte 精细抠图
| 参数 | 说明 |
|---|---|
mask | 指示抠哪个目标的提示掩码,不必精确,粗略覆盖主体即可 |
prompt_type | 视觉提示类型,见下表 |
inference_size | 默认 1024,与官方测试一致 |
is_transparent | 玻璃、纱、烟雾等透明物体务必打开 |
caption | 目标物体的英文描述。仅 SDMatte.pth 有效,SDMatte_plus.pth 请留空,见下文 |
point_radius | 仅 point_mask 生效。每个点晕开的高斯 sigma,默认 35 |
seed | 仅 point_mask 生效(10 个点是随机取的) |
prompt_type 选择:
| 取值 | 含义 | 适用 |
|---|---|---|
bbox_mask | 取掩码外接框作为提示 | 默认,官方测试脚本的主路径,通常最稳 |
mask | 直接用掩码本身 | 已有较准的粗分割时 |
point_mask | 在掩码内随机取 10 个点 | 仅 SDMatte.pth 支持,见下文 |
auto_mask | 不给定位信息 | 画面只有单一主体 |
官方 README 里,SDMatte 与 SDMatte*(即 SDMatte_plus)的训练集不同:
前者含 RefMatte(指代表达式抠图数据集,点提示与文本提示的来源),
后者用 COCO-Matte 替换了它。这导致 plus 版不具备点提示与文本指代能力:
SDMatte.pth | SDMatte_plus.pth | |
|---|---|---|
bbox_mask / mask / auto_mask | ✅ | ✅ |
point_mask | ✅ MAD 0.0135 | ❌ 输出全黑(max 仅 0.079) |
caption 语义 | ✅ 填对小幅提升 | ❌ 无作用,填了反而更差 |
caption 实测(羊驼图,MAD 越低越好):
| caption | SDMatte | SDMatte_plus |
|---|---|---|
""(留空) | 0.01120 | 0.01135 ← 最好 |
"alpaca"(语义正确) | 0.01072 ← 最好 | 0.01160 ← 最差 |
"tree"(语义错误) | 0.01111 | 0.01119 |
在 SDMatte 上,语义正确的描述确实更准;在 plus 上语义完全失效甚至反向,
说明它只是给 cross-attention 注入了噪声扰动,并非在理解文本。
结论:用 SDMatte_plus.pth 时保持 caption 留空、prompt_type 用 bbox_mask;
想用点提示或文本指代,请换 SDMatte.pth。节点在 point_mask 输出接近全黑时会打印警告。
加载图像 ──────────────┬──> SDMatte 精细抠图 ──> alpha (MASK)
│ ▲ └──> cutout (IMAGE)
任意分割节点 ──> mask ──┘ │
SDMatte 加载器 ───────────────────┘
mask 可以来自任何粗分割来源(SAM、rembg、手绘遮罩皆可)——SDMatte 的职责正是把粗糙边缘细化。
用官方效果图中的羊驼原图(绒毛边缘)跑本节点,与官方给出的 GT alpha 对比:
| 指标 | 数值 |
|---|---|
| MAD(平均绝对误差) | 0.0113 |
| MSE | 0.0026 |
| SAD | 0.807 千像素 |
(GT 取自官方效果图截图,含有损压缩与水印,故存在固有误差下限。)
各配置对输出的实际影响(透明玻璃杯,差异像素指偏差 > 0.05 的占比):
| 对照项 | 平均差 | 差异像素占比 |
|---|---|---|
inference_size 1024 vs 512 | 0.082 | 32.4% |
is_transparent 关 vs 开 | 0.059 | 25.0% |
官方 [F,T,F] vs 误用 [T,T,T] 条件分配 | 0.026 | 18.8% |
结论:分辨率影响最大,建议保持 1024;抠透明物体时 is_transparent 必须打开。
同一张图、同一份权重、同一台机器,对跑 ComfyUI-SDMatte 与本节点,以官方公布的 alpha 为参照:
| 实现 | 配置 | MAD ↓ |
|---|---|---|
| 本节点 | 官方 configs/SDMatte.py,bbox 提示,fp32 | 0.0113 |
| ComfyUI-SDMatte | 默认(trimap 提示 + mask_refine) | 0.0884 |
| ComfyUI-SDMatte | 关闭 mask_refine | 0.0885 |
相差 7.8 倍,且其输出肉眼可见地发灰、边缘晕开。
主因是视觉提示类型:官方 configs/SDMatte.py 固定 aux_input="bbox_mask",
而其 aux_input_list 只含 point_mask / bbox_mask / mask —— trimap 从未作为视觉提示参与训练。
ComfyUI-SDMatte 传 aux_input="trimap",把模型推到了没训练过的输入模式上,
且该分支的 trimap_coords 恒为 [0,0,1,1],定位信息全部丢失。
开不开它的 mask_refine 几乎不影响这一结论(0.0884 vs 0.0885),说明问题不在后处理。
若与其它 SDMatte 实现效果对不上,按影响从大到小排查:
视觉提示类型(影响最大)。必须用官方训练过的 bbox_mask / mask / point_mask,
并传入真实的归一化坐标。用 trimap 当视觉提示是模型没见过的用法。
UNet 配置来源。SDMatte 在标准 SD 2.1 的 UNet 配置上额外定义了
bbox_time_embed_dim / point_embeddings_input_dim / bbox_embeddings_input_dim 三个字段。
误用原版 SD 2.1 的 config.json 会缺这些字段,只能猜默认值,猜错则相应权重被
strict=False 静默丢弃。本节点直接分发官方配置,并在缺字段时直接报错而非猜测。
transformers 版本。官方权重用 transformers 4.x 保存,CLIPTextModel 内部裹了一层
text_model;transformers 5.x 起该层被移除,导致 text_encoder 的 372 个权重键名对不上、
被整体静默丢弃、停留在随机初始化。本节点会按当前环境自动增删该前缀。
条件分配。官方 use_encoder_hidden_states_list=[False, True, False] 决定 UNet
下采样/中间/上采样三段各接收哪种条件,漏传会退化成 [True, True, True]。
实测单独影响不大(羊驼 MAD 0.01135 → 0.01148),透明物体上更明显。
权重对齐校验。本节点在加载后校验键的完整性,一旦有权重未被覆盖或未被使用就中止并报错。 这类问题不会让模型崩溃,只会让输出质量悄悄下降,是最难排查的一类,因此宁可停下也不放行。
全程 fp32、1024 分辨率,且不做任何启发式后处理(不做阈值裁剪、对比度拉伸之类的"优化"), 输出即模型原始 alpha。
分类: Rui-Node🐶/AI模型🤖
功能描述:
连接 ZenMux 聚合平台(OpenAI 兼容协议),一个节点即可调用其收录的所有文本类模型(Anthropic、OpenAI、Google、DeepSeek、Qwen 等 20 家厂商、130+ 模型)。支持文本生成与多模态图像理解(最多 6 张图)。
特色功能:
价格直接标在选项上: 每个模型后缀形如 [入$0.2/M 出$1.25/M],即输入/输出每百万 token 的美元价格,选型时一目了然
快速筛选: 模型列表按「厂商/模型名」排序聚类,同厂商模型天然相邻;在下拉的搜索框输入厂商前缀(如 qwen/、anthropic/)即可只看该厂商的模型
离线可用的模型清单: 模型与价格来自随包分发的 zenmux/models_snapshot.json;价格有变动时运行 python zenmux/build_snapshot.py 即可重新拉取更新
旧工作流兼容: 价格快照更新后,旧工作流里保存的带旧价格标签仍能正确解析出模型 id,不会失效
单次消耗统计: usage_stats 输出本次运行的 token 用量、输出字数与费用换算(按快照单价计算,汇率可调),格式:
token消耗,输入:1234,输出:567
输出文字数量:328
模型类型:openai/gpt-5.4-nano [入$0.2/M 出$1.25/M]
价格换算,美元:0.000955,人民币:0.006876
自动参数兼容: 部分模型弃用或不支持某些采样参数(如 claude-sonnet-5 弃用 temperature、gpt-5 reasoning 系要求 max_completion_tokens)。节点会在收到相关 400 错误时自动剔除或改名该参数并重试,无需手动调整;剔除动作会打印到 ComfyUI 控制台。正常请求不受影响、无额外开销。
输入参数:
api_key (STRING): ZenMux 平台的 API Key(在 zenmux.ai 控制台获取)model (选择): 模型(带价格标注),默认 openai/gpt-5.4-nanosystem_prompt (STRING): 系统提示词user_prompt (STRING): 用户提示词seed (INT): 随机种子temperature (FLOAT, 可选): 采样温度,默认 0.7,范围 0.0 ~ 2.0top_p (FLOAT, 可选): 核采样阈值,默认 1.0max_tokens (INT, 可选): 最大输出 token 数,默认 1024image_1 ~ image_6 (IMAGE, 可选): 多模态图像输入(所选模型需支持 image 输入)detail (选择, 可选): 图像分析细节等级,auto/low/highimage_max_size (INT, 可选): 发送前图像最长边缩放上限,默认 1024base_url (STRING, 可选): API 地址,默认 zenmux.ai/api/v1(无需写 https://,节点会自动补全)proxy_url (STRING, 可选): HTTP/HTTPS 代理地址,如 127.0.0.1:7890usd_to_cny (FLOAT, 可选): 美元兑人民币汇率,默认 7.2,用于 usage_stats 的人民币换算,可按当日牌价调整输出:
text (STRING): 模型生成的文本内容model_id (STRING): 实际调用的模型 id(如 openai/gpt-5.4-nano),便于下游记录usage_stats (STRING): 单次运行的 token 消耗、输出文字数量(按字符计,含标点)与费用统计(四行文本,格式见上);请求失败时记为 0 消耗,token 数缺失或单价未知的项显示 ?使用场景:
网络自动重连:
线上跑批时最常见的失败不是参数错,而是链路抖动 —— 典型报错是
SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol')),
即 TLS 握手/传输被中途打断。这类失败重连一次往往就好了,因此节点内置了重连机制。
| 参数 | 默认 | 说明 |
|---|---|---|
max_retries | 3 | 网络失败后的自动重连次数,0 = 不重连 |
timeout | 180 | 单次请求超时秒数,超时计入重连次数 |
会重连:SSL 握手被打断(SSLEOFError)、连接被重置、连接/读超时、
响应体传到一半截断(ChunkedEncodingError / JSON 解析失败),
以及 429 限流与 5xx 服务端临时故障。
不重连:参数类 400、鉴权类 401/403、404 —— 这些重试多少次都是同样结果,
重连只会拖慢报错。
退避策略:1s → 2s → 4s → 8s → 16s 指数增长,每次叠加 ±25% 随机抖动。
抖动不是可有可无的装饰 —— 一条工作流里常有多个 API 节点同时失败,没有抖动它们会在
同一毫秒一起重连,把刚缓过来的服务端再打垮一次。服务端返回 Retry-After 头时以它为准。
与「自适应参数重试」的关系:两者是不同层次,互不消耗额度。参数自适应处理的是 「这个模型不认这个参数」(HTTP 400),网络重连处理的是「没拿到完整响应」。 参数被剔除后的 payload 会在后续重连中保留,不会重蹈覆辙。
重连过程会打印到控制台,例如:
[Rui-Node] 越光: 连接失败(SSLError),1.1s 后重连(第 1/3 次)
[Rui-Node] 越光: 第 2 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
分类: Rui-Node🐶/文本处理📝
功能描述:
输入 Markdown 文本,输出按阅读器级排版渲染的图片(IMAGE)。视觉规范对标 GitHub / Typora:标题层级字号(2.0/1.5/1.25/1.0/0.875/0.85 倍正文)、H1/H2 底部分隔线、引用左竖条、代码块圆角底色 + 等宽字体 + 语言标签、表格圆角外框 + 表头加粗底色 + 斑马纹 + 列对齐、任务清单勾选框、彩色 Emoji。纯 PIL 实现,无额外依赖。
支持的 Markdown 语法:
标题 #~######、段落(单换行即硬换行)、粗体、斜体、行内代码、删除线、链接、有序/无序/嵌套列表、任务清单 - [x]、引用 >(可嵌套)、围栏代码块、表格(:---: 对齐语法)、分割线 ---;表格与正文中的 Emoji 以系统彩色字体渲染。
输入参数:
markdown (STRING): Markdown 文本size_preset (选择): 常用尺寸快选(1080×1440 / 1080×1920 / 1080×1080 / 1920×1080 / A4 等),选 custom 时使用下方宽高width / height (INT): 精确尺寸(64~8192px,custom 时生效)font (选择): 字体,列表来自 Ruinode/font 目录(ttf/otf/ttc 均可,放入后刷新页面即出现在下拉;同族粗体文件如 msyhbd 会自动配对用于渲染粗体,无粗体文件时描边模拟)theme (选择): 浅色 / 深色 / 米色三套阅读器配色body_size、h1_size ~ h6_size (STRING, 可选): 各级字号,auto(默认)按输出尺寸二分搜索「恰好优雅填满画布」的字号,各级也可分别填数字精确指定letter_spacing (STRING, 可选): 字间距像素,默认 autoline_spacing (STRING, 可选): 行高倍数(如 1.8),默认 auto(正文 1.65)max_chars_per_line (STRING, 可选): 单行文字字数上限,达到即换行;默认 auto(按像素宽自然换行)输出:
image (IMAGE): 渲染结果,固定为所选宽高;内容超高时按现有字号裁剪并在控制台提示使用场景:
⚠️ 重要:不要用 WAS 的「Text Multiline」节点喂 Markdown
WAS Node Suite 的「Text Multiline」会把 # 开头的行当注释删除,标题行会凭空消失,还会做动态提示词替换。请改用本套件的 多行文本框(原样输出),或直接在本节点的 markdown 输入框里粘贴文本。
分类: Rui-Node🐶/文本处理📝
功能描述:
把输入的多行文本一字不动输出为 STRING:不删注释行、不做动态提示词/通配符/token 替换。专门用来安全承载 Markdown、代码等格式敏感文本(WAS 的「Text Multiline」会把 # 开头的行当注释吃掉,喂 Markdown 时标题会消失)。
输入参数:
text (STRING): 多行文本输出:
text (STRING): 与输入完全一致的文本使用场景:
# 标题的原样文本分类: Rui-Node🐶/图像调节🎨
功能描述:
给输入图像铺满一层平铺的文字水印,常用于版权标注、样图防盗、批量打标。文字按交错网格平铺,整体旋转后从中心裁切与原图等大的区域,因此任意旋转角度下四角也都被水印覆盖,不留空白。支持中英文混排与多行文案(用换行分隔),逐字符绘制以支持字间距。批量图像逐张处理。
输入参数:
image (IMAGE): 输入图像text (STRING, 多行): 水印文案,支持换行分隔的多行文本font (选择): 字体,列表来自 Ruinode/font 目录(ttf/otf/ttc,放入后刷新页面即出现,与 Markdown 节点共用同一套字体扫描)font_size (INT): 文字大小(像素),默认 48,范围 8~500angle (FLOAT): 水印整体旋转角度(度),默认 30,范围 -180~180density (FLOAT): 水印密度,综合控制行间距与同行水印之间的间距,值越大越密,默认 1.0,范围 0.1~5.0letter_spacing (INT): 字间距,单条文案内相邻字符的额外间距(像素,可为负),默认 0,范围 -20~200opacity (FLOAT): 水印透明程度,0=完全透明(原样返回),100=完全不透明,默认 35,范围 0~100color (STRING): 水印文字颜色,支持 #RRGGBB / #RGB / "r,g,b" / 常见英文色名(white、red、yellow…),默认 #FFFFFF输出:
image (IMAGE): 叠加水印后的图像使用场景:
分类: Rui-Node🐶/抠图✂️
功能描述:
全自动去背景抠图,不需要任何提示,输入图像直接输出 alpha。模型为 feyn 开源的 FeyNobg(Apache-2.0),在 BiRefNet(CAAI AIR 2024)基础上扩展:Swin-Large 主干 + 梯度注意力 / 图像块注入 / 多尺度输入三项增强,原生 1024×1024 推理,权重约 1.05GB。
与 SDMatte 精细抠图 的分工:
模型准备:
首次运行会自动从 HuggingFace 下载到 ComfyUI/models/nobg/FeyNobg(约 1.05GB)。也可手动下载 config.json、preprocessor_config.json、model.safetensors 放入该目录。
输入参数:
image (IMAGE): 输入图像model_name (选择): models/nobg 下的模型目录,未找到时自动下载resolution (选择): 推理分辨率,默认 1024(模型原生训练分辨率)。调低省显存但边缘变粗;调高不一定更好,可能出现结构断裂precision (选择): fp32(默认)/ fp16。实测两者输出一致(同图 alpha 均值均为 0.657),fp16 显存减半且明显更快,推荐优先用 fp16device (选择): auto / cpualpha_threshold (FLOAT, 可选): 前景判定阈值,默认 0.5。见下方「主体半透明发灰怎么救」alpha_softness (FLOAT, 可选): 阈值两侧过渡带宽度,默认 1.0 = 完全不处理keep_aspect_ratio (BOOLEAN, 可选): 保持宽高比(等比缩放 + 边缘延展补边),默认关闭invert_mask (BOOLEAN, 可选): 反转 alpha,默认前景为白输出:
alpha (MASK): 抠图 alpha,值域 [0,1]cutout (IMAGE): 去背景图(黑底)。需要透明 PNG 时,把 alpha 接到 JoinImageWithAlpha 一类节点实测数据(1139×1280 人物插画,RTX 显卡):
| 配置 | 耗时 | 前景占比 |
|---|---|---|
| fp32 @1024 | 12.4s(含首次加载) | 0.659 |
| fp16 @1024 | 2.4s | 0.659 |
| fp32 @768 | 2.2s | 0.656 |
发丝、飘带、细链条等高频细节均能完整分离,边缘为自然的半透明过渡而非硬边。
主体「整片半透明发灰」怎么救:
模型对拿不准的区域会输出 0.5 上下的中间值,表现为整个人物/物体呈半透明。模型本身没有开放任何控制该行为的参数(use_gradient_attention 等是训练时固化的架构参数,推理期不可调),因此节点在后处理层提供了一对色阶参数:
| alpha_threshold | alpha_softness | 效果 |
|---|---|---|
| 0.5 | 1.0 | 默认,原样输出,一个像素都不动 |
| 0.35 | 0.3 | 推荐,半透明像素占比 1.49% → 0.31%(降 79%),主体均值几乎不变 |
| 0.5 | 0.0 | 硬二值化,锯齿硬边,抠头发/玻璃慎用 |
原理是以 threshold 为中心、softness 为宽度取一段区间线性拉伸到 [0,1]:区间以下压成全透明,以上提成全不透明,区间内保留平滑过渡。默认参数下该区间恰好是 [0,1],等于恒等变换。
两点边界必须说明:
softness 越小,发丝等真实半透明细节损失越多,是一对权衡。长图形变:模型固定吃 1024×1024,默认把图直接拉伸成正方形(与官方训练方式一致)。手机截图这类 1:2 以上的长图横向会被压到一半,可开 keep_aspect_ratio 改为等比缩放 + 边缘延展补边、推理后裁掉补边。实测 2.36:1 的图半透明占比 0.1192 → 0.1041。该选项与训练分布不同,属试验性,常规比例建议保持关闭。
实现说明(两个坑,都已在节点内处理):
预处理依赖:上游 nobg 的预处理模块继承 transformers>=5.4 的 TorchvisionBackend,而 ComfyUI 常见环境仍是 transformers 4.x,直接引入会报 No module named 'transformers.image_processing_backends'。本节点内嵌了 nobg 推理子集(feynobg/)并重写了预处理,数值规格与官方逐项对齐(1024 双线性抗锯齿缩放 + ImageNet 标准化;后处理先 sigmoid 再缩放),无需升级 transformers。同时绕开了上游 AutoModel 里会联网查 tags 的 model_info(),保证离线可用。
权重键名不兼容(更隐蔽):FeyNobg 的权重用 transformers 5.x 导出,其 SwinBackbone 的模块命名与 4.x 不同(bb.swin.* 多一层、attention 从 self.query/key/value 重构为 q/k/v_proj、前馈层 mlp.fc1/fc2 对应 intermediate.dense/output.dense)。若不处理,958 个参数只有 405 个能对上,整个 backbone 形同随机初始化——模型照样跑完不报错,但输出的 alpha 几乎全黑(实测 max 0.02、mean 0.000)。节点内做了键名重映射(按环境自动判断是否需要),并严格校验:除确定性 buffer relative_position_index 与 backbone 末端未使用的 bb.layernorm 外,任何缺失/多余都直接报错中止,绝不接受静默劣化的结果。
分类: Rui-Node🐶/抠图✂️
功能描述:
全自动去背景,不需要任何提示。模型为 Lucida(MIT),是 BiRefNet_HR 的微调版,训练目标是攻克多数开源抠图模型的短板:伪装物体、透明材质(玻璃)、文字与 Logo、VFX 光效、插画。权重约 885MB(220M 参数,Swin-Large 主干)。
作者在 203 图 9 类别基准上的 MAE(越低越好):
| 类别 | Lucida | 商业参考 |
|---|---|---|
| 文字 / Logo 保留 | 0.0091 | 0.0123 |
| 插画 | 0.0092 | — |
| 伪装物体 | 0.0270 | — |
| 印刷设计 / 贴纸 | 0.0235 | — |
| 总体 | 0.0257 | — |
模型准备:
首次运行自动下载到 ComfyUI/models/lucida/lucida.safetensors。也可手动下载仓库的 model.safetensors,改名为 lucida.safetensors 放入该目录。
输入参数:
image (IMAGE): 输入图像model_name (选择): models/lucida 下的权重文件,未找到时自动下载precision (选择): fp16(默认)/ fp32device (选择): auto / cpualpha_threshold / alpha_softness (FLOAT, 可选): 遮罩色阶,默认 (0.5, 1.0) 为恒等变换。用法同 FeyNobg 节点keep_aspect_ratio (BOOLEAN, 可选): 保持宽高比,默认关闭invert_mask (BOOLEAN, 可选): 反转 alpha输出:
alpha (MASK) / cutout (IMAGE,黑底)⚠ 没有分辨率选项:模型内部 Config.size=1024 且 decoder 走 patch split,与 1024 输入绑定,因此不像 FeyNobg 那样可调分辨率。
三个抠图节点怎么选:
| 节点 | 特点 | 适用 |
|---|---|---|
| Lucida | 全自动,把半透明材质也算前景 | 文字/Logo、插画、玻璃、发光特效、伪装物体 |
| FeyNobg | 全自动,只找主要主体 | 常规主体照片,要求背景剥离干净 |
| SDMatte | 需框/掩码提示 | 画面里多个主体、只抠其中一个 |
实测对比(同图、同参数,本仓库两个全自动节点):
| 测试图 | Lucida 前景占比 | FeyNobg 前景占比 |
|---|---|---|
| 动漫插画(人物 + 云 + 栏杆) | 0.391 | 0.098 |
| 游戏场景图 | 0.395 | 0.378 |
| 人物插画 | 0.315 | 0.336 |
第一张图差异最大,肉眼核对后确认不是精度高低,而是「前景」的定义不同:FeyNobg 只抠出人物,云与栏杆全部排除;Lucida 除人物外还把半透明的云判为前景(灰度 alpha)并保留了栏杆——这与它专门训练透明材质的目标一致。所以两者是互补关系:要干净剥离主体用 FeyNobg,要保住文字/玻璃/光效等半透明元素用 Lucida。建议在自己的素材上实测再定,示例工作流已把两者并联便于对照。
⚠ alpha_softness 调小会把玻璃、发光这类真实半透明一并压实,而这正是 Lucida 的强项,务必按素材取舍。
实现说明:
模型代码(birefnet.py / BiRefNet_config.py,2250 行)内嵌在 lucida/ 子包,不使用 trust_remote_code——那会在运行时从 HuggingFace 拉取并执行远程 Python 代码,ComfyUI 场景下既不该联网也不该执行随时可变的远程代码;内嵌后版本固定、可离线、可审计。构造时传 bb_pretrained=False,避免联网下载 Swin 的 ImageNet 预训练权重。预处理规格与 BiRefNet 系一致,直接复用 FeyNobg 节点那份已验证实现。权重加载同样做严格校验(除窗口尺寸推出的确定性 buffer 外,任何失配直接报错中止)。
分类: Rui-Node🐶/图像调节🎨
功能描述:
把普通图像转成能直接当素材用的像素画。与"马赛克滤镜"的区别在于:滤镜只是把画面涂成方块、输出仍是原尺寸大图;而像素游戏要的是真实小分辨率、颜色数受控、边缘硬朗的 sprite。纯 numpy/PIL 实现,无额外依赖、无需模型权重。
三种模式:
| 模式 | 用途 |
|---|---|
| 按目标宽度 | 普通图/照片/插画 → 像素画,给输出宽度即可(高度按比例自动算) |
| 按像素块大小 | 每 N×N 原像素合成一个像素,已知放大倍数时最精确 |
| 自动检测网格 | 探测图中隐含的像素网格并还原——专治 AI 生成的伪像素图 |
第三种是重点:SD/Flux 生成的"像素风"图往往是 1024×1024,看着像素风,实际网格歪斜、边缘带抗锯齿、颜色成千上万,直接进引擎会糊。
输入参数:
image (IMAGE) / mask (MASK, 可选): 接抠图节点的 alpha 会按同一网格降采样并二值化成硬边mode / target_width / pixel_size: 见上表downsample (选择): 主导色 dominant(默认,取块内最多的颜色,不会凭空造出新颜色)/ median / mean(会糊边) / centerpalette (选择): 不量化 / 自适应 k-means(CIELAB 空间聚类)/ 自适应 median cut / PICO-8 (16色) / Game Boy (4色绿) / 黑白 1-bit / 灰阶 4·8·16 级palette_size (INT): 自适应调色板的颜色数。8dither (选择): 无 / Bayer 2×2·4×4·8×8 / Floyd-Steinberg / 随机噪声output_scale (INT): 1 = 真实像素尺寸(导出素材必须用 1);>1 仅为在 ComfyUI 里看清,放大是整数倍纯复制不插值dither_strength / mask_threshold / seed (可选)输出: image (IMAGE) / mask (MASK) / info (STRING,含检测到的网格与置信度)
方案选型(研究后的结论):
Pixel Snapper(Sprite Fusion,MIT)解决的是「伪像素图 → 完美像素图」,思路是检测网格 + 按主导色重采样;而「普通图 → 像素画」是另一个问题,核心在降采样方式与调色板量化。本节点把两条路做进同一节点,算法为自研实现。网格检测按公开研究的要点处理了两类经典误判:
评分用单元内方差而非相邻像素差分:差分对模糊极敏感,而 AI 伪像素图的边界都带抗锯齿,尖峰被摊平后压不住内容周期(开发中实测:4 像素的网格被判成 24~28)。改用组内方差后,过大的 s 会因单元跨越多个真实色块导致方差爆掉而被天然压制。
实测数据:
| 测试项 | 结果 |
|---|---|
| 干净放大图(k=2~16,各 3 组) | 27/27 全对,零八度错误 |
| 退化图(模糊+噪点,模拟 AI 伪像素图) | 10/15 |
| 非方形网格(9×6)、相位偏移 (3,5) | 全部正确 |
| 普通插画(无网格) | 正确判定为"未检出" |
| 端到端还原(32×32 放大 10 倍 + 模糊噪点) | 还原回 32×32,与真值 MAE 0.0049 |
| 完美像素校验(8× 放大抽样 == 1× 输出) | True(整数倍纯复制,无插值) |
⚠ 自动检测对干净放大图几乎必中,对模糊严重的图约 2/3 命中率。info 输出会给出检测到的网格与置信度,结果不对时改用「按像素块大小」手动指定即可。
分类: Rui-Node🐶/图像调节🎨
功能描述:
用于 8 方向行走动画 制作管线:把每帧都排布着 8 个朝向的雪碧图序列,一次拆成 8 条各自独立、可直接成片的动画序列,并完成方向编号与分组。
完整管线与分工:
| 步骤 | 由谁完成 |
|---|---|
| 角色图 → 八方向静态图 | GPTimage2 / Holopix Universal Edit 等 |
| 静态图 → 循环行走视频 | Seedance 首尾帧等 |
| 视频 → 序列帧 | 从文件读用 VHS「Load Video」;接在视频生成节点后面用原生「Get Video Components」 |
| 抽帧(降帧率) | VHS「Select Every Nth Image」 |
| 抠图(提供语义级 alpha) | Lucida / BiRefNet 等 |
| 拆分 + 编号 + 分组 + 8 队列输出 | 本节点 |
| 8 组透明 PNG 序列帧 | SaveImage(4 通道输入会自动存成 RGBA) |
| 8 个透明 webm | VHS「Video Combine」,format=video/webm + pix_fmt=yuva420p |
整条链路只有拆分环节是缺失的,其余全部复用成熟实现。
两个示例工作流:
一体化工作流的关键是打通 VIDEO → IMAGE:视频生成节点输出的是 ComfyUI 的 VIDEO 类型,而 VHS「Load Video」只能从文件读、接不上。用 ComfyUI 原生的「Get Video Components」(image/video 分类)即可,输入 VIDEO、输出 images/audio/fps,不需要装任何额外插件。
⚠️ 帧率两处必须匹配:Seedance 出的是 24fps,抽帧间隔与输出帧率要对应,否则 webm 播放速度不对。
select_every_nth=3 ↔ frame_rate=8;要 12fps 就用 2 ↔ 12;要全量 24fps 就用 1 ↔ 24。
输入参数:
images (IMAGE): 视频转出的序列帧masks (MASK, 可选): 上游抠图节点的遮罩,强烈建议接上(见下方「透明通道怎么来」)grid_cols / grid_rows / empty_cells: 网格布局。3×3 中间留空即 empty_cells=4(序号行优先、从 0 开始)direction_names (STRING): 按「跳过空格后的先后顺序」命名,默认 SW,S,SE,W,E,NW,N,NE,对应行 1 面向观众、行 3 背对观众的排布bg_mode / bg_threshold: 透明通道来源,见下edge_shrink / decontaminate: 治白边,见下fragment_threshold (FLOAT): 清掉面积不足主体这一比例的连通碎片expand_beyond_cell (BOOLEAN): 务必开启,允许角色超出格子边界auto_crop / crop_padding: 按内容裁剪透明通道怎么来(关系到成品质量,别用默认凑合):
| bg_mode | 原理 | 代价 |
|---|---|---|
| 已带透明通道(默认推荐) | 用上游 Lucida / FeyNobg 的语义级 alpha | 需要跑模型 |
| 白底转透明 | 纯颜色阈值 + 边缘连通性 | 角色身上的白衣服会被啃出破洞 |
| 不处理 | 输出不透明(仍按角色范围裁剪不切断) | — |
颜色阈值法的死穴在于它按「离白色多远」估 alpha,白衬衫本身就接近白、alpha 天生偏低,一旦收边压白边,衬衫就被啃穿。实测同一素材、同等白边水平下:
| 方案 | 白边强度 | 主体被啃面积 |
|---|---|---|
| 颜色阈值法(收边 0.35) | 0.0261 | 0.0373 |
| Lucida alpha(收边 0.2) | 0.0256 | 0.0242(少 35%) |
Lucida 一次就能识别整张雪碧图的全部 8 个角色(各格前景占比 0.18~0.24,中间空格 0.002),肉眼比对:模型 alpha 的白衬衫完好,阈值法的衬衫上布满背景色斑块。
治白边的两个参数:
edge_shrink(主力):把边缘那圈「几乎全是背景」的半透明像素收掉。白底素材的边缘像素本就掺了白,不收掉贴到深色背景就发白。实测白边强度:0 → 0.048;0.2 → 0.026;0.5 → 0.016。配模型 alpha 用 0.15~0.25,配阈值法要 0.35 以上decontaminate(辅助):颜色反溢出,按 观察色 = 前景×a + 白×(1-a) 反解真正的前景色。单独用只改善约 3%(因为观察色本身已经太白,反解出来还是白),必须和收边配合输出: dir_1 ~ dir_8 (IMAGE,4 通道 RGBA) + info (STRING)
锚点对齐:让 8 个方向尺寸统一、切换朝向不跳
做游戏素材时这一步是刚需。不开对齐时,每个方向各按自己的内容裁剪,8 个方向出 8 种尺寸,角色在各自画面里的位置也不一致——游戏里切换朝向角色就会跳一下。人工做法是「一帧一帧手动对位置」,本节点把它自动化了:
| 参数 | 说明 |
|---|---|
align_mode | 锚点对齐·统一画布(默认)/不对齐 |
anchor_type | 脚底中心(默认)/包围盒底边中心/包围盒中心 |
align_scope | 逐帧对齐·脚底钉死(默认)/按方向统一平移 |
为什么锚点取「脚底中心」而不是包围盒中心:角色站在地面上,脚底才是它在世界里的位置;而斗篷、披风、手杖会把包围盒拽向一侧。所以 y 取最低的不透明行,x 取底部窄带的水平质心——那些外挂物基本不会垂到脚底,走路时两脚一前一后,窄带质心正好落在两脚之间,也就是人真正站立的点。
实测(97 帧真实素材):
| 输出尺寸 | 各方向锚点散布 | 同方向跨帧位移 | |
|---|---|---|---|
| 不对齐 | 8 种各不相同 | x 48.9px / y 27px | — |
| 按方向统一平移 | 统一 267×372 | x 7.1px / y 4px | 13~23px(保留摆动) |
| 逐帧对齐(默认) | 统一 284×367 | x 0.76px / y 0px | ~1px |
默认选逐帧对齐,是因为行走循环本就该原地播放、位移交给游戏代码,sprite 内部不该有整体漂移;而 AI 生成的视频往往有(实测同方向跨帧漂移达 22px)。角色本就该有前后摆动的动作(挥剑、跳跃)则改用「按方向统一平移」。
info 输出会给出统一画布尺寸、锚点坐标、以及 Unity/Godot 的归一化 pivot(左下为原点),例如:
统一画布 267×372,锚点(脚底中心)位于 (144.5, 346.0)
Unity/Godot 归一化 pivot(左下为原点):(0.5411, 0.0699)
把那个 pivot 填进引擎的 Sprite 设置,8 个方向就能共用同一套坐标。
三个关键设计:
用固定网格而非连通区域拆分(本仓库的素材拆分节点)。连通区域按包围盒排序,角色走动时位置浮动,一旦跨过排序行界方向就会错乱——上百帧里错一帧整条动画就废了;且每个 sprite 按各自 bbox 裁剪、尺寸不一,无法合成视频。固定网格没有这两个问题。(连通区域拆分依然更适合单张静态合图,两者各有用途。)
白底转透明用边缘连通性判断。角色常穿白衣服,按亮度阈值一刀切会把白衬衫一起掏空。这里只把与画面边缘相连的白色判为背景,被角色包围的白色一律保留。
裁剪框取全序列并集。逐帧各自裁剪会导致尺寸不一且角色在帧间跳动;取并集则整条序列尺寸一致、位置连贯。
实测(97 帧 834×1112 的真实素材):
| 项目 | 结果 |
|---|---|
| 拆分耗时 | 约 4 秒,8 方向 × 97 帧 |
| 输出尺寸 | 150×335 ~ 206×326,方向内完全一致 |
| 方向稳定性 | 跨帧内容重心极差 0.5~12 px(走路摆动的正常范围,无跳变) |
| 碎片清理效果 | E 方向 172×370 → 150×335,重心极差 8.0 → 0.5 px |
| webm 透明 | 导出后回读透明像素占比 0.635,与素材一致 |
⚠️ 验证 webm 透明时容易被误导:alpha 存放在 WebM 的独立边带里,ffprobe 看主流会显示 yuv420p,用 ffmpeg 默认解码回读也会得到全不透明——这是内置 vp9 解码器不处理 alpha 边带所致,并非文件丢了透明。需显式加 -c:v libvpx-vp9 解码才能读到。播放器与 Unity/Godot 走的是 libvpx,能正确读取。
分类: Rui-Node🐶/AI模型🤖
功能描述:
通过越光(Nebula)聚合平台调用其收录的文本类模型。OpenAI 兼容协议,chat 端点 https://llm.ai-nebula.com/v1/chat/completions。参数、输出与容错行为与 ZenMux 节点 保持一致,便于两者互换。
模型清单(25 个,价格单位 USD / 百万 token):
| 厂商 | 模型 | 输入 | 输出 |
|---|---|---|---|
| OpenAI | gpt-5.6-sol | 4.75 | 5.00 |
| gpt-5.6-terra | 2.375 | 2.50 | |
| gpt-5.6-luna | 0.95 | 1.00 | |
| gpt-4.1 / gpt-4.1-mini | 2.00 / 0.40 | 8.00 / 1.60 | |
| gpt-4o / gpt-4o-mini | 2.50 / 0.15 | 10.00 / 0.60 | |
| o4-mini / o3-mini | 1.10 | 4.40 | |
| Anthropic | claude-opus-5 | 5.00 | 5.00 |
| claude-opus-4-7 / 4-6 | 15.00 | 75.00 | |
| claude-sonnet-5 | 2.00 | 2.00 | |
| claude-sonnet-4-6 | 3.00 | 15.00 | |
| claude-haiku-4-5-20251001 | 0.80 | 4.00 | |
| claude-fable-5 | 3.00 | 15.00 | |
| DeepSeek | deepseek-v4-pro | 2.19 | 8.76 |
| deepseek-v4-flash(默认) | 0.10 | 0.30 | |
| deepseek-r1-250528 | 0.55 | 2.19 | |
| deepseek-v3-250324 | 0.27 | 1.10 | |
| Kimi | kimi-k3 | 2.86 | 2.86 |
| kimi-k2.7-code / k2.6 / k2.5 / k2-thinking | 1.00 | 4.00 |
输入参数: 与 ZenMux 节点相同——api_key、model(下拉带价签)、system_prompt、user_prompt、seed,以及可选的 temperature、top_p、max_tokens、image_1~image_6、detail、image_max_size、base_url、proxy_url、usd_to_cny。
输出: text / model_id / usage_stats(五行:token 消耗、输出字数、厂商、模型与单价、美元与人民币费用)
与 ZenMux 节点的三点差异:
yueguang/model_registry.py 里——少一个联网环节,也不会因拉取失败导致下拉变空。价格变动时改那张表即可。gpt-4o 而非 openai/gpt-4o)。下拉里同厂商靠排序聚在一起,搜索时输 gpt / claude / deepseek / kimi 过滤。deepseek-v4-flash($0.10/$0.30),官方示例也用它,默认值便宜可避免误触发时产生意外费用。沿用的实战经验:
base_url 默认值不带 ://——ComfyUI 前端会吞掉文本框里的协议片段(本仓库为此修过多次),协议由后端自动补全temperature、或要求用 max_completion_tokens 取代 max_tokens,命中这类 400 时会剔除/改名后自动重试,正常请求零额外开销VALIDATE_INPUTS 宽松放行:价格表更新后旧工作流里保存的标签不再逐字匹配,但只要能解析出 model id 就放行,不会让整个工作流失效网络自动重连:
线上跑批时最常见的失败不是参数错,而是链路抖动 —— 典型报错是
SSLError(SSLEOFError(8, 'EOF occurred in violation of protocol')),
即 TLS 握手/传输被中途打断。这类失败重连一次往往就好了,因此节点内置了重连机制。
| 参数 | 默认 | 说明 |
|---|---|---|
max_retries | 3 | 网络失败后的自动重连次数,0 = 不重连 |
timeout | 180 | 单次请求超时秒数,超时计入重连次数 |
会重连:SSL 握手被打断(SSLEOFError)、连接被重置、连接/读超时、
响应体传到一半截断(ChunkedEncodingError / JSON 解析失败),
以及 429 限流与 5xx 服务端临时故障。
不重连:参数类 400、鉴权类 401/403、404 —— 这些重试多少次都是同样结果,
重连只会拖慢报错。
退避策略:1s → 2s → 4s → 8s → 16s 指数增长,每次叠加 ±25% 随机抖动。
抖动不是可有可无的装饰 —— 一条工作流里常有多个 API 节点同时失败,没有抖动它们会在
同一毫秒一起重连,把刚缓过来的服务端再打垮一次。服务端返回 Retry-After 头时以它为准。
与「自适应参数重试」的关系:两者是不同层次,互不消耗额度。参数自适应处理的是 「这个模型不认这个参数」(HTTP 400),网络重连处理的是「没拿到完整响应」。 参数被剔除后的 payload 会在后续重连中保留,不会重蹈覆辙。
重连过程会打印到控制台,例如:
[Rui-Node] 越光: 连接失败(SSLError),1.1s 后重连(第 1/3 次)
[Rui-Node] 越光: 第 2 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
分类: Rui-Node🐶/抠图✂️
功能描述:
纯数学去底,等效 After Effects 的 Unmult。纯色背景上的合成图满足 C = αF + (1-α)B,背景色 B 已知时可反解出前景色 F 与透明度 α。不需要模型推理,速度快、结果是精确解,且能真实保留半透明层次——这是语义抠图模型给不了的。
输入参数:
image (IMAGE): 待去底图像,支持批量(序列帧/视频帧逐帧处理)bg_color (STRING): 要去除的背景色,#RRGGBB。常用 #000000 / #FFFFFF / #00FF00 / #FF00FF黑点 (FLOAT, 滑块): 低于此值的 alpha 归零,用于清除背景残留噪点。调太高会丢边缘细节白点 (FLOAT, 滑块): 高于此值的 alpha 归一,用于让主体更实。调太低会让边缘硬化主体保护 (BOOLEAN): 是否采纳 subject_mask。关闭时即便已连线也完全不采纳,等同纯 Unmult——想对比「有无 AI 介入」时拨这个开关即可,不必拔线subject_mask (MASK, 可选): 接抠图节点输出的 alpha,节点执行 max(unmult_α, subject_mask) 合并后两项用中文参数名 + display: slider,界面上就是两条滑块,与 LayerStyle 的 BiRefNet Ultra 观感一致。函数内部用 **kwargs 接收(中文名不能直接做函数形参),并兼容旧的 alpha_low/alpha_high 调用。
输出: rgba_image (IMAGE,4 通道) / alpha (MASK)
实测(构造已知合成图反推,验证还原精度):
| 场景 | alpha 平均误差 | 前景色平均误差 |
|---|---|---|
| 发光素材 @ 黑底 | 0.0000 | 0.0000 |
| 发光素材 @ 白底 | 0.0000 | 0.0000 |
| 发光素材 @ 绿幕 | 0.0000 | 0.0000 |
数学上是精确解,三种底色都能完美还原。
⚠ 适用边界与破解办法:
| 素材 | 纯 Unmult | 接 subject_mask 后 |
|---|---|---|
| 光效、火焰、烟雾、粒子、UI 特效 | ✅ 最佳选择,半透明层次完整保留 | 一般不需要 |
| 绿幕/品红等与素材反差大的底色 | ✅ 实体素材也能扣干净 | 一般不需要 |
| 黑底 + 暗色实体 | ❌ 暗部会被当成背景扣掉 | ✅ 已解决 |
实测同一个实体素材(alpha 真值恒为 1,下半部分接近纯黑):
| 条件 | 暗部还原 alpha |
|---|---|
| 黑底,不接 mask | 0.080 ← 黑头发、深色衣服、鞋子被扣穿 |
| 黑底,接 mask 且「主体保护」启用 | 1.000 ✅ |
| 黑底,接 mask 但「主体保护」关闭 | 0.080(与不接完全一致,开关确实生效) |
| 绿幕,不接 mask | 0.940 ✓ 本来就正常 |
根因是黑底 unmult 本质在用"亮度当不透明度",这对发光物成立、对实体不成立。破法是接一路语义抠图(Lucida / FeyNobg / BiRefNet)的 alpha 进 subject_mask:主体区域强制不透明,主体之外仍走 Unmult 的精确半透明。两者各取所长——语义模型负责"哪里是主体",Unmult 负责"边缘有多透"。
四个抠图节点怎么选:
| 节点 | 原理 | 适用 |
|---|---|---|
| Unmult | 纯数学反解 | 纯色底的光效/火焰/粒子;绿幕素材 |
| Lucida | 语义模型 | 文字/Logo、插画、玻璃、伪装物体 |
| FeyNobg | 语义模型 | 常规主体照片,要求背景剥离干净 |
| SDMatte | 语义模型 + 提示 | 画面里多个主体、只抠其中一个 |
Rui-Node🐶 致力于为 ComfyUI 用户提供实用、高效的节点工具集。🐶 是我们的项目标志,代表着忠诚、友好和可靠。
分类: Rui-Node🐶/视频🎬
功能描述: 从带透明通道的视频中解出 RGBA 序列帧,alpha 不丢失。用来解决一个很常见、 但排查起来相当隐蔽的问题:带 alpha 的 WebM 用常规加载视频节点读进来,透明通道没了。
为什么会丢——根因:
带 alpha 的 WebM(VP8/VP9)并不把透明度放在主视频流里。主流仍然是 yuv420p,
alpha 被单独压成第二路,藏在 Matroska 的 BlockAdditional 边带中,容器上只留
一条 alpha_mode=1 的元数据作记号。
ffmpeg 内置的 vp9 / vp8 解码器根本不读这条边带,只有 libvpx-vp9 / libvpx
才会。VideoHelperSuite 等常见加载节点走的是默认解码器,于是拿到的每一帧 alpha 恒为 255。
实测同一个文件的三条路径:
| 解码路径 | alpha 结果 |
|---|---|
PyAV 默认(解码器 vp9) | 全 255,丢失 |
| ffmpeg 默认 | 全 255,丢失 |
显式 -c:v libvpx-vp9 | min=0 max=255,全透明 87.2%、半透明 2.0%,完整 |
本节点显式指定 libvpx 解码器,并以 rgba 原始像素流读回,因此连半透明边缘也一并保留。 对 MOV/qtrle、ProRes 4444 等本身带 alpha 通道的格式同样适用。
输入参数:
video: 从 input 目录选择视频文件强制帧率 (FLOAT): 按指定帧率重采样,0=保持原始帧率帧数上限 (INT): 最多读取多少帧,0=读完整段(达到上限立即中止解码)跳过前N帧 (INT): 丢弃开头若干帧间隔 (INT): 每隔几帧取一帧,1=每帧都要自定义宽度 / 自定义高度 (INT): 0=保持原始;只填一边时另一边按比例换算解码器: 自动(探测到 alpha_mode=1 的 VP8/VP9 时自动换 libvpx)/ 强制 libvpx(保 alpha) / 默认解码器视频路径 (STRING, 可选): 绝对路径,填写后优先于下拉选择输出:
rgba_image (IMAGE): 4 通道 RGBA 序列帧alpha (MASK): 透明通道rgb_image (IMAGE): 3 通道,供只吃 3 通道的下游节点使用帧数 (INT) / 帧率 (FLOAT)存成带透明通道的 PNG 序列帧:
rgba_image 直接接 ComfyUI 原生「保存图像」节点即可。原生节点的像素处理是
Image.fromarray(...),4 通道数组会被识别成 RGBA 模式,存出的 PNG 完整保留 alpha——
不需要额外的保存节点。实测 33 帧全部为 RGBA 模式,与内存中的 alpha 逐像素零误差。
关于预览发黑:
ComfyUI 的预览区不渲染透明,看到黑底是正常现象,不代表 alpha 丢了。
判断是否成功以 alpha 输出接遮罩预览为准,或直接看存出的 PNG 文件。
示例工作流: example_workflow/透明视频转PNG序列帧.json
关于节点内视频预览被裁切:
如果节点下方的视频预览只显示画面的一部分(按原始像素尺寸渲染、超出部分被切掉),
根因不在本节点,而是 comfyui-art-venture 插件的一处全局 CSS 误伤。
它在 web/upload.js 里为自家的 LoadVideoFromUrl 注入了这条规则:
.comfy-img-preview video {
width: var(--comfy-img-preview-width);
height: var(--comfy-img-preview-height);
}
选择器是全局的,会盖掉 ComfyUI 官方的 width:100%; height:100%;而这两个 CSS 变量
只在 art-venture 自家节点的 DOM 上定义,其它节点上取到空值 —— 变量为空时整条声明失效,
<video> 退回固有尺寸(例如 640×640)撑破容器,容器 overflow:hidden 于是把画面裁掉。
本仓库通过前端扩展 web/rui_video_preview_fit.js 修正,注入两条规则:
.comfy-img-preview.rui-video-fit video 强制 100% + object-fit:contain,
容器标记由拦截 node.videoContainer 赋值时打上,必定生效100% 的回退值 —— 变量有值时行为完全不变
(art-venture 自己的节点不受影响),仅在变量为空这种本就失效的情况下恢复官方行为实测(640×640 视频、347px 宽容器):修复前 video 渲染为 640×640 溢出被裁; 修复后为 347×347 完整显示。
该修复随
WEB_DIRECTORY加载,需要重启 ComfyUI 后端并刷新浏览器才会生效。
本项目遵循开源协议,欢迎使用和贡献。
Happy Creating with Rui-Node🐶! 🎨✨
50 commits
Python
99.3%