简单计算
经常会有想要简单地进行四则运算的场景,比如将图像尺寸精准地减半,或者调整 Batch Size 等。 让我们来看看用于这些操作的节点。
推荐的自定义节点
因为功能简单,实现它的节点要找的话有很多,但只要有以下任意一个自定义节点就足够了。(要是能作为核心节点实现就好了……)
- ComfyUI_essentials
- 虽然是一个优秀的节点,但因为几乎处于归档状态,如果发现优秀的替代节点我会进行替换。
- ComfyUI-Custom-Scripts
这里我们以 ComfyUI_essentials 的 Simple Math 节点为例进行讲解。
Simple Math

{
"id": "d7badf9d-4187-470d-a5b2-a2c4296f9f8e",
"revision": 0,
"last_node_id": 16,
"last_link_id": 11,
"nodes": [
{
"id": 4,
"type": "PrimitiveInt",
"pos": [
637.447265625,
501.5946960449219
],
"size": [
210,
82
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
1
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
25,
"fixed"
]
},
{
"id": 13,
"type": "PrimitiveInt",
"pos": [
637.447265625,
650.788330078125
],
"size": [
210,
82
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
10
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
7,
"fixed"
]
},
{
"id": 14,
"type": "PrimitiveInt",
"pos": [
637.447265625,
799.9819946289062
],
"size": [
210,
82
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
11
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
100,
"fixed"
]
},
{
"id": 3,
"type": "SimpleMath+",
"pos": [
899.1307983398438,
630.86669921875
],
"size": [
210,
98
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "a",
"shape": 7,
"type": "*",
"link": 1
},
{
"name": "b",
"shape": 7,
"type": "*",
"link": 10
},
{
"name": "c",
"shape": 7,
"type": "*",
"link": 11
}
],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
5
]
},
{
"name": "FLOAT",
"type": "FLOAT",
"links": []
}
],
"properties": {
"cnr_id": "comfyui_essentials",
"ver": "9d9f4bedfc9f0321c19faf71855e228c93bd0dc9",
"Node name for S&R": "SimpleMath+"
},
"widgets_values": [
"a * b - c"
],
"color": "#232",
"bgcolor": "#353"
},
{
"id": 8,
"type": "PreviewAny",
"pos": [
1160.396240234375,
630.86669921875
],
"size": [
210,
88
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 5
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PreviewAny"
},
"widgets_values": []
}
],
"links": [
[
1,
4,
0,
3,
0,
"*"
],
[
5,
3,
0,
8,
0,
"*"
],
[
10,
13,
0,
3,
1,
"*"
],
[
11,
14,
0,
3,
2,
"*"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1.2100000000000004,
"offset": [
-537.447265625,
-402.4211423259136
]
},
"frontendVersion": "1.26.8",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
可以在 a, b, c 中分别输入数值。
利用这些变量,写成 a * b - c 这样,就可以进行简单的算术运算。
此外,由于它是直接使用 Python 的表达式,所以也可以进行稍微高级一点的计算。
a // b # 整数除法(舍去小数点以下)
a % b # 取余(除法的余数)
a ** b # 幂运算(乘方)
(a + b) * c # 用括号指定优先顺序
abs(a - b) # 求绝对值
min(a, b) # 返回最小值
max(a, b) # 返回最大值
round(a / b) # 四雪五入
(a > b) * 1 # 逻辑表达式:条件数值化(若 a > b 则为 1, 否则为 0)
(a == b) * 1 # 逻辑表达式:判定是否相等
(a != b) * 1 # 逻辑表达式:判定是否不同
int 类型与 float 类型
数字也有“类型 (Type)”。
在 ComfyUI 中主要使用 int 和 float 这两种。
- int 类型:仅整数(例:
512,32,1)- Batch Size 或 图像分辨率等
- float 类型:可处理小数(例:
0.7,1.5,24.0)- KSampler 的 strength 或 视频的 fps 等
如果不以适当的类型进行输入输出,就无法连接到节点。 虽然可能会有“全部用 float 不就行了吗”这样的吐槽,但为了计算效率和精度,它们是被区分开的……习惯就好。
类型的转换
顺便提一下,将数值通过一次 Simple Math 节点,就可以进行 int ↔ float 的转换。
即使输入是 float,如果输出目标是 int,它也会自动进行转换。

{
"id": "d7badf9d-4187-470d-a5b2-a2c4296f9f8e",
"revision": 0,
"last_node_id": 24,
"last_link_id": 20,
"nodes": [
{
"id": 21,
"type": "PrimitiveFloat",
"pos": [
651.47802734375,
628.9332275390625
],
"size": [
210,
58
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "FLOAT",
"type": "FLOAT",
"links": [
18
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PrimitiveFloat"
},
"widgets_values": [
12.3
]
},
{
"id": 8,
"type": "PreviewAny",
"pos": [
1160.396240234375,
628.9332275390625
],
"size": [
210,
88
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 5
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PreviewAny"
},
"widgets_values": []
},
{
"id": 24,
"type": "PreviewAny",
"pos": [
1162.296630859375,
815.1841430664062
],
"size": [
210,
88
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 20
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PreviewAny"
},
"widgets_values": []
},
{
"id": 22,
"type": "PrimitiveInt",
"pos": [
651.47802734375,
815.1841430664062
],
"size": [
210,
82
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
19
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.56",
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
999,
"fixed"
]
},
{
"id": 23,
"type": "SimpleMath+",
"pos": [
906.8873291015625,
815.1841430664062
],
"size": [
210,
98
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "a",
"shape": 7,
"type": "*",
"link": 19
},
{
"name": "b",
"shape": 7,
"type": "*",
"link": null
},
{
"name": "c",
"shape": 7,
"type": "*",
"link": null
}
],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": []
},
{
"name": "FLOAT",
"type": "FLOAT",
"links": [
20
]
}
],
"properties": {
"cnr_id": "comfyui_essentials",
"ver": "9d9f4bedfc9f0321c19faf71855e228c93bd0dc9",
"Node name for S&R": "SimpleMath+"
},
"widgets_values": [
"a"
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 3,
"type": "SimpleMath+",
"pos": [
905.9371337890625,
628.9332275390625
],
"size": [
210,
98
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "a",
"shape": 7,
"type": "*",
"link": 18
},
{
"name": "b",
"shape": 7,
"type": "*",
"link": null
},
{
"name": "c",
"shape": 7,
"type": "*",
"link": null
}
],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
5
]
},
{
"name": "FLOAT",
"type": "FLOAT",
"links": []
}
],
"properties": {
"cnr_id": "comfyui_essentials",
"ver": "9d9f4bedfc9f0321c19faf71855e228c93bd0dc9",
"Node name for S&R": "SimpleMath+"
},
"widgets_values": [
"a"
],
"color": "#323",
"bgcolor": "#535"
}
],
"links": [
[
5,
3,
0,
8,
0,
"*"
],
[
18,
21,
0,
3,
0,
"*"
],
[
19,
22,
0,
23,
0,
"*"
],
[
20,
23,
1,
24,
0,
"*"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1.2100000000000006,
"offset": [
-551.47802734375,
-528.9332275390625
]
},
"frontendVersion": "1.26.8",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
【小技巧】输入栏中的简易计算
如果是不用节点也能解决的简单计算,直接在输入栏中写入计算式,输入的就是计算后的值。

Power Puter (rgthree)
使用 rgthree-comfy 添加的 Power Puter,可以获取图像尺寸,或者使用 if 语句,这已经几乎是编程了,但可以进行更复杂的处理。

{
"id": "c05fc5ca-84cc-4a12-9e1a-3dbddf62dcde",
"revision": 0,
"last_node_id": 7,
"last_link_id": 6,
"nodes": [
{
"id": 3,
"type": "LoadImage",
"pos": [
3602.8349609375,
-692.7393798828125
],
"size": [
214.080078125,
314
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.59",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"example.png",
"image"
]
},
{
"id": 4,
"type": "PrimitiveInt",
"pos": [
3610.344970703125,
-312.99334716796875
],
"size": [
210,
82
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "INT",
"type": "INT",
"links": [
2
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.59",
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
512,
"fixed"
]
},
{
"id": 5,
"type": "PreviewAny",
"pos": [
4196.6748046875,
-692.7393798828125
],
"size": [
210,
88
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 3
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.59",
"Node name for S&R": "PreviewAny"
},
"widgets_values": []
},
{
"id": 1,
"type": "Power Puter (rgthree)",
"pos": [
3866.253662109375,
-692.7393798828125
],
"size": [
281.0826721191406,
259.6524963378906
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "a",
"type": "*",
"link": 1
},
{
"name": "b",
"type": "*",
"link": 2
},
{
"name": "c",
"type": "*",
"link": null
}
],
"outputs": [
{
"label": "STRING",
"name": "*",
"shape": 3,
"type": "STRING",
"links": [
3
]
}
],
"properties": {
"cnr_id": "rgthree-comfy",
"ver": "0fb1e239a903e93ef626a8c20589b38f46e39dff"
},
"widgets_values": [
{
"outputs": [
"STRING"
]
},
"# テンソルの形状から画像サイズを取得\n_, height, width, _ = a.shape\n\n# 条件に応じたメッセージを作成\nif width < b:\n result = f\"This image is smaller than {b}\"\nelse:\n result = f\"This image is larger than {b}\"\n\n# 結果を出力\nprint(result)\n\n# 結果を返す\nreturn result"
],
"color": "#232",
"bgcolor": "#353"
}
],
"links": [
[
1,
3,
0,
1,
0,
"*"
],
[
2,
4,
0,
1,
1,
"*"
],
[
3,
1,
0,
5,
0,
"*"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1.2284597357368363,
"offset": [
-3502.8349609375,
792.7393798828125
]
},
"frontendVersion": "1.27.3",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}