7
This commit is contained in:
+46
@@ -0,0 +1,46 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# Virtual Environment
|
||||
venv/
|
||||
ENV/
|
||||
env/
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# ComfyUI specific
|
||||
*.ckpt
|
||||
*.safetensors
|
||||
*.vae
|
||||
*.pt
|
||||
*.pth
|
||||
*.bin
|
||||
*.onnx
|
||||
*.engine
|
||||
|
||||
# OS specific
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 ComfyUI-UniversalToolkit
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1 +1,70 @@
|
||||
# ComfyUI-ImageToolkit
|
||||
# ComfyUI-UniversalToolkit
|
||||
|
||||
## 简介
|
||||
本插件为 ComfyUI 提供多尺寸空白单元(image/mask/latent)生成节点,结构完全遵循 ComfyUI 插件标准。
|
||||
|
||||
## 目录结构
|
||||
```
|
||||
ComfyUI-UniversalToolkit/
|
||||
├── main.py
|
||||
├── image_utils.py
|
||||
├── requirements.txt
|
||||
├── README.md
|
||||
└── nodes/
|
||||
├── __init__.py
|
||||
└── image_nodes.py
|
||||
```
|
||||
|
||||
## 安装方法
|
||||
1. 将本目录放入 ComfyUI 的 custom_nodes 目录下。
|
||||
2. 安装依赖:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
3. 重启 ComfyUI。
|
||||
|
||||
## 节点说明
|
||||
### 空单元生成器(EmptyUnitGenerator)
|
||||
- 输入参数:
|
||||
- 图像大小:small/medium/large
|
||||
- 构图比例:1:1/3:4/16:9
|
||||
- 颜色:white/black/gray/red/green/blue
|
||||
- 输出:
|
||||
- image:空白图像
|
||||
- mask:空白蒙版
|
||||
- latent:空白潜空间
|
||||
|
||||
## 依赖
|
||||
- Pillow
|
||||
- numpy
|
||||
|
||||
## 功能特点
|
||||
- 模块化设计,各功能独立封装
|
||||
- 支持多种基础数据类型处理
|
||||
- 提供直观的节点界面
|
||||
- 完善的错误处理和参数验证
|
||||
|
||||
## 已实现功能
|
||||
- 多尺寸、多比例空白图像/mask/latent 一键生成
|
||||
- 支持 small(sd1.5)、medium(flux/sdxl)、large(high resolution)三种尺寸
|
||||
- 支持 1:1、3:4、16:9 等常见比例
|
||||
- 支持自定义颜色
|
||||
|
||||
## 使用方法
|
||||
1. 启动 ComfyUI
|
||||
2. 在节点菜单中找到 "UniversalToolkit" 分类
|
||||
3. 选择需要的节点并配置参数
|
||||
4. 连接节点并运行工作流
|
||||
|
||||
## 开发计划
|
||||
- [ ] 添加更多图像处理节点
|
||||
- [ ] 添加数据类型转换节点
|
||||
- [ ] 添加逻辑处理节点
|
||||
- [ ] 优化节点界面
|
||||
- [ ] 添加更多示例工作流
|
||||
|
||||
## 贡献指南
|
||||
欢迎提交 Issue 和 Pull Request!
|
||||
|
||||
## 许可证
|
||||
MIT License
|
||||
@@ -0,0 +1,9 @@
|
||||
from .universal_toolkit_node import EmptyUnitGenerator
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"EmptyUnitGenerator": EmptyUnitGenerator,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"EmptyUnitGenerator": "空单元生成器",
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Pillow
|
||||
numpy
|
||||
@@ -0,0 +1,88 @@
|
||||
from PIL import Image
|
||||
import numpy as np
|
||||
import torch
|
||||
import re
|
||||
|
||||
class EmptyUnitGenerator:
|
||||
CATEGORY = "UniversalToolkit"
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
# 标准比例选项
|
||||
STANDARD_RATIOS = [
|
||||
("1:1", [(1024, 1024), (2048, 2048)]),
|
||||
("3:2", [(1200, 800), (800, 1200)]),
|
||||
("4:3", [(1600, 1200), (1200, 1600)]),
|
||||
("8:5", [(1280, 800), (800, 1280)]),
|
||||
("16:9", [(1920, 1080), (1080, 1920)]),
|
||||
("21:9", [(2520, 1080), (1080, 2520)]),
|
||||
]
|
||||
standard_options = []
|
||||
for ratio, sizes in STANDARD_RATIOS:
|
||||
for w, h in sizes:
|
||||
orientation = "横向" if w >= h else "纵向"
|
||||
standard_options.append(f"{ratio} {orientation} ({w}x{h})")
|
||||
|
||||
# 社交媒体分辨率
|
||||
social_options = [
|
||||
"Instagram Portrait - 1080x1350",
|
||||
"Instagram Square - 1080x1080",
|
||||
"Instagram Landscape - 1080x608",
|
||||
"Instagram Stories/Reels - 1080x1920",
|
||||
"Facebook Landscape - 1080x1350",
|
||||
"Facebook Marketplace - 1200x1200",
|
||||
"Facebook Stories - 1080x1920",
|
||||
"TikTok - 1080x1920",
|
||||
"YouTube Banner - 2560x1440",
|
||||
"LinkedIn Profile Banner - 1584x396",
|
||||
"LinkedIn Page Cover - 1128x191",
|
||||
"LinkedIn Post - 1200x627",
|
||||
"Pinterest Pin Image - 1000x1500",
|
||||
"CivitAI Cover - 1600x400",
|
||||
"OpenArt App - 1500x1000",
|
||||
]
|
||||
|
||||
return {
|
||||
"required": {
|
||||
"ratio_type": (["standard", "social media"], {"default": "standard", "label": "比例类型"}),
|
||||
"ratio": (standard_options, {"default": standard_options[0], "label": "尺寸/比例", "dynamic": True, "depends_on": ["ratio_type"]}),
|
||||
"image_color": (["white", "black", "gray", "red", "green", "blue"], {"default": "white", "label": "Image Color"}),
|
||||
"batch": ("INT", {"default": 1, "min": 1, "max": 16, "step": 1, "label": "输出组数(batch)"}),
|
||||
},
|
||||
"optional": {},
|
||||
"dynamic": {
|
||||
"ratio": lambda params: standard_options if params.get("ratio_type", "standard") == "standard" else social_options
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "MASK", "LATENT")
|
||||
RETURN_NAMES = ("image", "mask", "latent")
|
||||
FUNCTION = "generate"
|
||||
|
||||
def generate(self, ratio_type, ratio, image_color, batch):
|
||||
# 解析分辨率
|
||||
if ratio_type == "standard":
|
||||
m = re.search(r"\((\d+)x(\d+)\)", ratio)
|
||||
width, height = int(m.group(1)), int(m.group(2))
|
||||
else:
|
||||
m = re.search(r"(\d+)x(\d+)", ratio)
|
||||
width, height = int(m.group(1)), int(m.group(2))
|
||||
COLOR_OPTIONS = {
|
||||
"white": (255, 255, 255),
|
||||
"black": (0, 0, 0),
|
||||
"gray": (128, 128, 128),
|
||||
"red": (255, 0, 0),
|
||||
"green": (0, 255, 0),
|
||||
"blue": (0, 0, 255),
|
||||
}
|
||||
color_rgb = COLOR_OPTIONS[image_color]
|
||||
images = []
|
||||
masks = []
|
||||
latents = []
|
||||
for _ in range(batch):
|
||||
image = torch.from_numpy(np.array(Image.new("RGB", (width, height), color_rgb))).float() / 255.0
|
||||
mask = torch.from_numpy(np.array(Image.new("L", (width, height), 0))).unsqueeze(-1).float() / 255.0
|
||||
latent = torch.from_numpy(np.zeros((height, width, 4), dtype=np.float32))
|
||||
images.append(image)
|
||||
masks.append(mask)
|
||||
latents.append(latent)
|
||||
return tuple(images), tuple(masks), tuple(latents)
|
||||
@@ -0,0 +1,19 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "ComfyUI.UniversalToolkit",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "MultiBlankGenerator") {
|
||||
// 自定义节点UI
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const result = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
|
||||
|
||||
// 添加节点说明
|
||||
this.help = "生成指定尺寸和比例的空白图像、mask和latent";
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user