RUI-Nodes
Rui's workflow-specific custom node, written using GPT.
Nodes (28)
Make one image wear another's colors (without the pain)
Turn a shot script into a clean dialogue list
Stamp 'don't steal this' over your whole output, in one pass
Load images from anywhere, not just the input folder
Load Image, but it hands you the filename it used
Turn Markdown into a share-ready image without leaving ComfyUI
Pick one mask out of a pile and keep the leftovers
A chat-completions box that can also read your images
Sweep the page-narration lines out of your script
Alibaba's Qwen image-edit model, called from inside the graph
The missing step in the character-to-walk-cycle pipeline
One-click background removal that doesn't need a prompt
Your transparent WebM dies on import — this node is the alpha rescue
The matting model that keeps glass, text, and glow alive
Finally see what your masks actually cover
Real sprites from photos, and fake pixel art back to real
The matting node that refines rough masks
Load the SDMatte weights once and keep them hot in VRAM
Slice a sprite sheet into separate assets, automatically
Sprite splitting that keeps the transparency
The text node that won't eat your # headings
The mathematically exact way to cut a glow off a black background
The no-brainer desaturation node
Slice a storyboard script into individual shots
Five text boxes, one list — the lazy prompt-batching helper
Scrub the broken characters out of your text
25 LLMs behind one dropdown, with the prices printed on the labels
One key to 130+ LLMs, from Claude to DeepSeek, priced in the dropdown
Rui-Node🐶 - ComfyUI 图像处理节点集
Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理、文本处理、AI 模型集成和遮罩处理等多种功能。
📦 安装方法
- 将此文件夹复制到 ComfyUI 的
custom_nodes目录中 - 安装依赖:
pip install -r requirements.txt - 重启 ComfyUI
📋 节点目录
🎨 图像调节类
- 调整饱和度 / Saturation Adjustment
- 图像翻转 / Image Flip
- 颜色匹配器 / Color Matcher
- 素材拆分 / Sprite Splitter
- 素材拆分(带透明通道) / Sprite Splitter RGBA
- 满屏文字水印 / Full-Screen Text Watermark
- 像素化 / Pixelate
- 八方向序列拆分 / 8-Direction Sprite Split
- 半透明抠图 / Unmult Matting
- 加载透明视频 / Load Video (Alpha)
📁 文件存储与加载类
🤖 AI模型类
- 千问编辑图像生成 / Qwen Edit Image Generation
- SDMatte 精细抠图 / SDMatte Interactive Matting
- ZenMux API 连接 / ZenMux API Connector
- 越光 API 连接 / YueGuang API Connector
- FeyNobg 抠图 / FeyNobg Matting
- Lucida 抠图 / Lucida Matting
📝 文本处理类
- 镜头分词器 / Shot Splitter
- 对白提取器 / Dialogue Extractor
- 页面旁白删除器 / Page Narration Remover
- 文本列表制作器 / Text List Creator
- 转化为utf-8编码 / Convert to UTF-8
- Markdown转图片 / Markdown To Image
- 多行文本框(原样输出) / Text Box (Raw)
🎭 遮罩处理类
📖 节点详细说明
1. 调整饱和度 / Saturation Adjustment
分类: Rui-Node🐶/图像调节🎨
功能描述:
调整图像的色彩饱和度,可以创建黑白图像或增强色彩鲜艳度。
输入参数:
image(IMAGE): 输入图像saturation(FLOAT): 饱和度调整系数- 默认值: 1.0
- 范围: 0.0 ~ 5.0
- 步长: 0.1
- 说明:
- 0.0 = 完全无饱和度(黑白图像)
- 1.0 = 原始饱和度(不变)
-
1.0 = 增加饱和度
输出:
IMAGE: 调整后的图像
使用场景:
- 将彩色图像转换为黑白
- 增强图像色彩表现力
- 降低过于鲜艳的色彩
2. 图像翻转 / Image Flip
分类: Rui-Node🐶/图像调节🎨
功能描述:
对图像进行水平或垂直翻转操作。
输入参数:
image(IMAGE): 输入图像flip_direction(选择): 翻转方向- 选项: "水平" 或 "垂直"
- 默认值: "水平"
输出:
IMAGE: 翻转后的图像
使用场景:
- 镜像翻转图像
- 创建对称效果
- 调整图像方向
3. 按路径加载图像 / Load Image By Path
分类: Rui-Node🐶/文件存储与加载📁
功能描述:
从指定的文件路径加载图像文件,支持绝对路径输入。
输入参数:
image_path(STRING): 图像文件的完整路径- 默认值: "E:\ComfyUIModels\input\10\1.png"
- 支持格式: PNG、JPG、JPEG 等常见图像格式
输出:
IMAGE: 加载的图像
特殊处理:
- 如果文件不存在,返回 512x512 的黑色默认图像
- 自动将非 RGB 图像转换为 RGB 模式
使用场景:
- 从外部路径加载特定图像
- 批量处理指定目录的图像
- 加载非 ComfyUI 默认输入目录的图像
4. 千问编辑图像生成 / Qwen Edit Image Generation
分类: Rui-Node🐶/AI模型🤖
功能描述:
使用阿里云千问(Qwen)编辑模型 API 进行 AI 图像生成,支持多种控制模式。
输入参数:
image1~image4(IMAGE): 最多 4 张输入图像作为参考api_key(STRING): 阿里云 API 密钥base_url(STRING): API 基础 URL- 默认值: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image-generation/generation"
seed(INT): 随机种子- 默认值: -1(随机生成)
- 范围: -1 ~ 2147483647
control_mode(选择): 控制模式- 选项: reference, sketch, scribble, pose, canny, depth, hed, mlsd, normal, seg
- 默认值: "reference"
width(INT): 输出图像宽度- 默认值: 1024
- 范围: 512 ~ 2048
- 步长: 8
height(INT): 输出图像高度- 默认值: 1024
- 范围: 512 ~ 2048
- 步长: 8
输出:
IMAGE: AI 生成的图像
使用场景:
- AI 辅助图像创作
- 基于参考图生成新图像
- 多模态图像控制生成
5. 镜头分词器 / Shot Splitter
分类: Rui-Node🐶/文本处理📝
功能描述:
将包含多个分镜描述的脚本文本拆分成独立的分镜列表,支持按范围筛选导出。
输入参数:
input_text(STRING): 输入的多分镜描述脚本(多行文本)- 格式要求: 使用
<SHOT_XXX>...</SHOT_XXX>标签包裹每个分镜
- 格式要求: 使用
start_shot_num(INT, 可选): 开始导出的分镜编号- 默认值: 0(从第一个开始)
- 范围: 0 ~ 100
shot_count(INT, 可选): 导出的分镜数量- 默认值: 0(导出全部)
- 范围: 0 ~ 100
输出:
shot_descriptions(LIST): 拆分后的分镜描述列表summary(STRING): 总结信息
文本格式示例:
<SHOT_1>
第一个镜头的描述内容
</SHOT_1>
<SHOT_2>
第二个镜头的描述内容
</SHOT_2>
使用场景:
- 分镜脚本拆分
- 批量处理分镜描述
- 选择性导出特定范围的分镜
6. 对白提取器 / Dialogue Extractor
分类: Rui-Node🐶/文本处理📝
功能描述:
从分镜描述文本中自动提取旁白/对白内容。
输入参数:
input_text(STRING): 输入的分镜描述文本(多行文本)
输出:
dialogues(LIST): 提取的旁白/对白列表summary(STRING): 总结信息
识别模式:
- 支持格式 1:
旁白:[对白内容] - 支持格式 2:
旁白:对白内容 - 自动识别
<SHOT_XXX>标签中的旁白
使用场景:
- 从分镜脚本中提取对白
- 批量收集旁白文本
- 准备配音文本
7. 页面旁白删除器 / Page Narration Remover
分类: Rui-Node🐶/文本处理📝
功能描述:
删除文本中所有以"页面旁白:"或"页面旁白:"开头的整行内容。
输入参数:
input_text(STRING): 原始文本(多行文本)
输出:
clean_text(STRING): 移除页面旁白行后的文本
处理规则:
- 自动识别并删除以"页面旁白:"或"页面旁白:"开头的行
- 忽略行首行尾的空白字符
- 保留其他所有内容
使用场景:
- 清理脚本中的页面旁白
- 文本预处理
- 提取纯净对白内容
8. 文本列表制作器 / Text List Creator
分类: Rui-Node🐶/文本处理📝
功能描述:
将多个独立的文本段落组织成列表形式输出。
输入参数:
text1(STRING, 必需): 第一段文本(多行文本)text2~text5(STRING, 可选): 第 2~5 段文本(多行文本)
输出:
text_list(LIST): 文本列表(Python 列表格式)summary(STRING): 总结信息
处理规则:
- 自动过滤空文本
- 去除每段文本首尾的空白字符
- 保留内部段落结构
使用场景:
- 组织多段文本为列表
- 批量文本处理准备
- 文本分组管理
9. 遮罩筛选 / Mask Selector
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
对输入的多个遮罩进行排序并选择特定遮罩,同时输出剩余遮罩的合并结果。
输入参数:
masks(MASK): 输入的遮罩(可包含多个遮罩)sort_method(选择): 排序方法- 选项:
- "按面积排序 / By Area": 按遮罩面积从大到小排序
- "从左到右 / Left to Right": 按遮罩质心 X 坐标升序排序
- "从上到下 / Top to Bottom": 按遮罩质心 Y 坐标升序排序
- 默认值: "按面积排序 / By Area"
- 选项:
index(INT): 选择的遮罩编号(1-based 索引)- 默认值: 1
- 最小值: 1
- 说明: 如果超出范围会自动夹取到有效范围
输出:
选中遮罩 / Selected(MASK): 选中的单个遮罩剩余遮罩 / Remaining(MASK): 其他遮罩的合并结果信息 / Info(STRING): JSON 格式的详细信息total_masks: 遮罩总数selected_index: 选中编号sort_method: 排序方式selected_area: 选中遮罩的像素面积selected_center: 选中遮罩的质心坐标 [x, y]index_clamped: 编号是否越界被修正
使用场景:
- 从多个检测结果中选择特定目标
- 分离主体和背景遮罩
- 基于大小或位置筛选遮罩
10. 遮罩预览 / Mask Preview
分类: Rui-Node🐶/遮罩处理🎭
功能描述:
将遮罩以半透明彩色形式叠加显示在图像上,方便直观查看遮罩覆盖区域。节点自带预览功能,同时输出合成后的图像。
输入参数:
image(IMAGE): 作为底图的原始图像mask(MASK): 需要可视化的遮罩mask_color(选择): 遮罩显示颜色- 默认值: 红色 / Red
- 选项: 红色、绿色、蓝色、黄色、青色、品红、白色
opacity(FLOAT, 可选): 不透明度- 默认值: 0.5
- 范围: 0.0 ~ 1.0
- 步长: 0.05
输出:
图像 / Image(IMAGE): 合成了半透明彩色遮罩的图像
特性:
- 自动处理遮罩与图像的尺寸差异
- 节点界面直接显示预览效果
- 支持批量处理
- 7种预设颜色可选
- 可调节不透明度
使用场景:
- 检查分割结果的准确性
- 调试遮罩处理流程
- 多遮罩对比(使用不同颜色)
- 制作遮罩可视化图
11. 转化为utf-8编码 / Convert to UTF-8
分类: Rui-Node🐶/文本处理📝
功能描述:
删除输入字符串中所有非 UTF-8 编码字符(如孤立的代理对),确保输出的字符串符合 UTF-8 编码规范。
输入参数:
input_text(STRING): 需要处理的原始字符串(支持多行)
输出:
filtered_text(STRING): 过滤后的符合 UTF-8 规范的字符串log(STRING): 处理日志,包含移除字符的详细信息和统计总结
使用场景:
- 清理可能包含非法字符的文本数据
- 确保文本在保存或传输时的编码安全性
- 调试文本编码问题
12. OpenAI API 连接 / OpenAI API Connector
分类: Rui-Node🐶/AI模型🤖
功能描述:
连接 OpenAI 或兼容 API(如 DeepSeek、Moonshot 等),进行文本生成或多模态图像理解,支持最多 6 张图像同时输入。
输入参数:
api_url(STRING): API 接口地址- 默认值: "https://api.openai.com/v1/chat/completions"
api_key(STRING): API 密钥model(STRING): 模型名称- 默认值: "gpt-4o"
system_prompt(STRING): 系统提示词user_prompt(STRING): 用户提示词seed(INT): 随机种子,用于控制生成的随机性image_1~image_6(IMAGE, 可选): 最多 6 张输入图像- 说明: 用户有几张图就连接几个输入口,无需手动 Batch
- 规则: 节点内部会自动逐张处理每个输入图像,分别编码后发送到 API
- 优势: 不要求所有图像尺寸一致,512×512 和 511×768 之类的混合输入也可直接使用
temperature(FLOAT, 可选): 采样温度- 默认值: 0.3
- 范围: 0.0 ~ 2.0
max_tokens(INT, 可选): 最大输出 token 数- 默认值: 500
- 范围: 1 ~ 8192
detail(选择, 可选): 图像分析细节等级- 选项: low, high, auto
- 默认值: auto
image_max_size(INT, 可选): 单张图像最长边缩放上限- 默认值: 1024
- 范围: 256 ~ 4096
- 说明: 超过该尺寸的图像会在发送前按比例缩小,以减少 token 消耗与请求体积
proxy_url(STRING, 可选): HTTP/HTTPS 代理地址- 示例:
http://127.0.0.1:7890
- 示例:
输出:
text(STRING): 模型生成的文本内容
使用场景:
- 调用 LLM 进行文本生成
- 使用 Vision 模型进行单图或多图联合理解
- 连接本地或第三方兼容 OpenAI 协议的 API
- 对多张参考图做综合分析、比对与总结
13. 颜色匹配器 / Color Matcher
分类: Rui-Node🐶/图像调节🎨
功能描述:
将目标图像的颜色分布匹配到参考图像的颜色分布,支持多种匹配算法和混合调节。
输入参数:
reference_image(IMAGE): 作为颜色参考的图像moving_image(IMAGE): 需要改变颜色的目标图像match_method(选择): 匹配算法- 选项: "histogram" (直方图匹配), "mean_std" (均值标准差匹配), "none" (无匹配)
- 默认值: "histogram"
blend_factor(FLOAT): 混合系数- 默认值: 1.0
- 范围: 0.0 ~ 1.0
- 步长: 0.01
- 说明: 控制原图和匹配后图像的混合比例,1.0为完全使用匹配后图像
输出:
颜色匹配后图像(IMAGE): 颜色调整后的图像匹配信息(STRING): 记录了使用的匹配方式以及混合系数的日志信息
使用场景:
- 统一多张图像的色调风格
- 将素材无缝融合进背景
- 图像色彩风格迁移
14. 素材拆分 / Sprite Splitter
分类: Rui-Node🐶/图像调节🎨
功能描述:
从白色/浅色背景的合图(Sprite Sheet)中自动拆分出每个独立的美术元素,通过连通区域检测进行裁剪,并将每个独立元素作为图像列表输出。
输入参数:
图像(IMAGE): 输入的带有透明通道的合图图像(RGBA格式)最小面积过滤(像素数)(INT): 最小面积过滤- 默认值: 100
- 范围: 1 ~ 50000
- 说明: 面积小于此值(像素数)的连通区域将被过滤,避免拆分出噪点碎片。
裁剪边距(INT): 裁剪边距- 默认值: 2
- 范围: 0 ~ 50
- 说明: 每个元素裁剪时在包围盒外额外保留的像素边距。
排序方式(选择): 排序方式- 选项: "从左到右-从上到下", "从上到下-从左到右", "面积从大到小", "面积从小到大"
- 默认值: "从左到右-从上到下"
seed(INT): 随机种子- 默认值: 0
- 说明: 仅用于强制重新执行节点,不影响实际拆分结果。适用于线上部署时强制刷新缓存。
输出:
图像列表(IMAGE): 拆分后的多张图像列表,透明区域会用白色填充输出。
使用场景:
- 游戏素材合图切分
- 批量图标提取
- 白底素材自动裁剪
15. 素材拆分(带透明通道) / Sprite Splitter RGBA
分类: Rui-Node🐶/图像调节🎨
功能描述:
与标准素材拆分节点功能相同,但保留并额外输出 Alpha 透明通道,适用于需要透明背景的美术素材提取。
输入参数:
- 输入参数与 素材拆分 / Sprite Splitter 完全一致。
输出:
图像列表(IMAGE): 拆分后的多张 RGB 图像列表遮罩列表(MASK): 对应的多张 Alpha 透明通道遮罩列表,1.0代表不透明,0.0代表透明
使用场景:
- 提取带透明背景的游戏角色、道具素材
- 搭配
JoinImageWithAlpha等节点生成透明 PNG 图像
16. 加载图像(带文件名) / Load Image With Name
分类: 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
📝 注意事项
- 所有节点都兼容 ComfyUI 的标准图像处理流程
- 图像格式统一为 BHWC(批次、高度、宽度、通道)
- 图像值范围为 0.0 ~ 1.0 的浮点数
- 使用 AI 模型节点需要配置有效的 API 密钥
- 文本处理节点支持多行文本输入
- 所有节点名称采用中英双语显示
- 遮罩处理节点自动处理尺寸不匹配问题
17. SDMatte 精细抠图 / SDMatte Interactive Matting
基于 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 的横向实测
同一张图、同一份权重、同一台机器,对跑 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。
18. ZenMux API 连接 / ZenMux API Connector
分类: 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 数缺失或单价未知的项显示?
使用场景:
- 一个 Key 试遍多家厂商的模型,横向对比效果与成本
- 按预算选型:价格就写在下拉列表里,直接挑便宜的
- 调用 Claude / GPT / Gemini / DeepSeek 等做文本生成或图像理解
网络自动重连:
线上跑批时最常见的失败不是参数错,而是链路抖动 —— 典型报错是
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 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
19. Markdown转图片 / Markdown To Image
分类: 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): 渲染结果,固定为所选宽高;内容超高时按现有字号裁剪并在控制台提示
使用场景:
- 将 LLM 输出的 Markdown(如 ZenMux 节点的 text)直接转成可分享的长图
- 生成小红书 / 公众号风格的图文卡片、A4 打印稿
- 工作流内把结构化报告(含表格、代码)落成图像资产
⚠️ 重要:不要用 WAS 的「Text Multiline」节点喂 Markdown
WAS Node Suite 的「Text Multiline」会把 # 开头的行当注释删除,标题行会凭空消失,还会做动态提示词替换。请改用本套件的 多行文本框(原样输出),或直接在本节点的 markdown 输入框里粘贴文本。
20. 多行文本框(原样输出) / Text Box (Raw)
分类: Rui-Node🐶/文本处理📝
功能描述:
把输入的多行文本一字不动输出为 STRING:不删注释行、不做动态提示词/通配符/token 替换。专门用来安全承载 Markdown、代码等格式敏感文本(WAS 的「Text Multiline」会把 # 开头的行当注释吃掉,喂 Markdown 时标题会消失)。
输入参数:
text(STRING): 多行文本
输出:
text(STRING): 与输入完全一致的文本
使用场景:
- 为 Markdown转图片 提供含
#标题的原样文本 - 存放任何不希望被上游文本节点"加工"的内容
21. 满屏文字水印 / Full-Screen Text Watermark
分类: 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): 叠加水印后的图像
使用场景:
- 给出图 / 样片加满屏防盗水印
- 批量素材统一打上版权或"仅供参考"标注
22. FeyNobg 抠图 / FeyNobg Matting
分类: Rui-Node🐶/抠图✂️
功能描述:
全自动去背景抠图,不需要任何提示,输入图像直接输出 alpha。模型为 feyn 开源的 FeyNobg(Apache-2.0),在 BiRefNet(CAAI AIR 2024)基础上扩展:Swin-Large 主干 + 梯度注意力 / 图像块注入 / 多尺度输入三项增强,原生 1024×1024 推理,权重约 1.05GB。
与 SDMatte 精细抠图 的分工:
- FeyNobg:全自动、一步出图、速度快,适合批量去背景(画面主体明确时首选)
- 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],等于恒等变换。
两点边界必须说明:
- 只对已有一定响应的区域有效。模型压根没认出来的地方 alpha 接近 0,再降阈值也救不回来——那属于语义判断差异(BiRefNet-General 倾向保留画面全部前景,FeyNobg 更强调「找主要主体」),需要换模型或改用 SDMatte 指定目标。
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)。节点内做了键名重映射(按环境自动判断是否需要),并严格校验:除确定性 bufferrelative_position_index与 backbone 末端未使用的bb.layernorm外,任何缺失/多余都直接报错中止,绝不接受静默劣化的结果。
23. Lucida 抠图 / Lucida Matting
分类: 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 外,任何失配直接报错中止)。
24. 像素化 / Pixelate
分类: 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): 自适应调色板的颜色数。8~16 复古感强,32~64 细节更多dither(选择):无/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)解决的是「伪像素图 → 完美像素图」,思路是检测网格 + 按主导色重采样;而「普通图 → 像素画」是另一个问题,核心在降采样方式与调色板量化。本节点把两条路做进同一节点,算法为自研实现。网格检测按公开研究的要点处理了两类经典误判:
- 谐波(八度)错误:2s 与 s 得分往往接近,容易把 2 倍大小当真值 → 取得最高分后回查其真约数(octave killer)
- 内容周期冒充像素周期:画面里重复的纹理/花纹也形成周期 → 真网格对相位极其敏感、内容周期则不敏感,把「最佳相位与最差相位的分差」并入评分(anti-phase)
评分用单元内方差而非相邻像素差分:差分对模糊极敏感,而 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 输出会给出检测到的网格与置信度,结果不对时改用「按像素块大小」手动指定即可。
25. 八方向序列拆分 / 8-Direction Sprite Split
分类: 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 |
整条链路只有拆分环节是缺失的,其余全部复用成熟实现。
两个示例工作流:
- 八方向行走动画.json:从已有视频文件出发(VHS Load Video)
- 角色图到八方向行走动画(一体化).json:从角色图一路到成品,把生图、生视频、拆分、导出串成一条链
一体化工作流的关键是打通 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,能正确读取。
26. 越光 API 连接 / YueGuang API Connector
分类: 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里——少一个联网环节,也不会因拉取失败导致下拉变空。价格变动时改那张表即可。 - model id 不带厂商前缀(是
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 次重连后成功
若重连耗尽仍失败,错误信息会注明已重连次数,便于区分「网络确实不通」和「压根没重试」。
27. 半透明抠图 / Unmult Matting
分类: 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🐶
Rui-Node🐶 致力于为 ComfyUI 用户提供实用、高效的节点工具集。🐶 是我们的项目标志,代表着忠诚、友好和可靠。
📄 许可证
28. 加载透明视频 / Load Video (Alpha)
分类: 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🐶! 🎨✨