feat: Add Get Image or Mask Range From Batch (UTK) node

- 新增Get Image or Mask Range From Batch (UTK)节点到tools分类
- 支持从图像批次或遮罩批次中提取指定范围的元素
- 灵活的索引控制:支持正索引和-1(从末尾开始)
- 智能范围处理:自动处理超出范围的情况
- 双输入支持:可同时处理图像和遮罩批次
- 详细日志输出:显示提取的索引范围和数量
- 错误处理:提供清晰的错误信息指导用户
- 工具分类:归类到UniversalToolkit/tools分类下
- 提升批次处理工作流的灵活性和效率
- 更新版本到1.4.4并添加完整更新日志
This commit is contained in:
Cyber Dick Lang
2025-10-29 19:49:43 +08:00
parent 49a058ebe8
commit 9f2257e81d
3 changed files with 130 additions and 2 deletions
+24 -1
View File
@@ -8,13 +8,24 @@ A comprehensive toolkit for ComfyUI that provides various utility nodes for imag
:license: MIT, see LICENSE for more details. :license: MIT, see LICENSE for more details.
""" """
__version__ = "1.4.3" __version__ = "1.4.4"
__author__ = "CyberDickLang" __author__ = "CyberDickLang"
__email__ = "286878701@qq.com" __email__ = "286878701@qq.com"
__url__ = "https://github.com/whmc76" __url__ = "https://github.com/whmc76"
# 更新日志 # 更新日志
CHANGELOG = { CHANGELOG = {
"1.4.4": [
"新增Get Image or Mask Range From Batch (UTK)节点:",
"- 支持从图像批次或遮罩批次中提取指定范围的元素",
"- 灵活的索引控制:支持正索引和-1(从末尾开始)",
"- 智能范围处理:自动处理超出范围的情况",
"- 双输入支持:可同时处理图像和遮罩批次",
"- 详细日志输出:显示提取的索引范围和数量",
"- 错误处理:提供清晰的错误信息指导用户",
"- 工具分类:归类到UniversalToolkit/tools分类下",
"- 提升批次处理工作流的灵活性和效率",
],
"1.4.3": [ "1.4.3": [
"修复翻译API节点错误消息显示问题:", "修复翻译API节点错误消息显示问题:",
"- 修复API密钥获取网址在错误消息中不显示的问题", "- 修复API密钥获取网址在错误消息中不显示的问题",
@@ -726,6 +737,15 @@ except ImportError:
TEXT_TRANSLATOR_API_MAPPINGS = {} TEXT_TRANSLATOR_API_MAPPINGS = {}
TEXT_TRANSLATOR_API_DISPLAY = {} TEXT_TRANSLATOR_API_DISPLAY = {}
try:
from .nodes.tools.get_image_range_from_batch import \
NODE_CLASS_MAPPINGS as GET_IMAGE_RANGE_MAPPINGS
from .nodes.tools.get_image_range_from_batch import \
NODE_DISPLAY_NAME_MAPPINGS as GET_IMAGE_RANGE_DISPLAY
except ImportError:
GET_IMAGE_RANGE_MAPPINGS = {}
GET_IMAGE_RANGE_DISPLAY = {}
# 合并所有节点映射 # 合并所有节点映射
NODE_CLASS_MAPPINGS = {} NODE_CLASS_MAPPINGS = {}
@@ -765,6 +785,7 @@ NODE_CLASS_MAPPINGS.update(PROMPT_HELPER_MAPPINGS)
NODE_CLASS_MAPPINGS.update(COLOR_TO_MASK_MAPPINGS) NODE_CLASS_MAPPINGS.update(COLOR_TO_MASK_MAPPINGS)
NODE_CLASS_MAPPINGS.update(LAZY_SWITCH_MAPPINGS) NODE_CLASS_MAPPINGS.update(LAZY_SWITCH_MAPPINGS)
NODE_CLASS_MAPPINGS.update(TEXT_TRANSLATOR_API_MAPPINGS) NODE_CLASS_MAPPINGS.update(TEXT_TRANSLATOR_API_MAPPINGS)
NODE_CLASS_MAPPINGS.update(GET_IMAGE_RANGE_MAPPINGS)
# 合并显示名称映射 # 合并显示名称映射
NODE_DISPLAY_NAME_MAPPINGS = {} NODE_DISPLAY_NAME_MAPPINGS = {}
@@ -804,6 +825,7 @@ NODE_DISPLAY_NAME_MAPPINGS.update(PROMPT_HELPER_DISPLAY_MAPPINGS)
NODE_DISPLAY_NAME_MAPPINGS.update(COLOR_TO_MASK_DISPLAY) NODE_DISPLAY_NAME_MAPPINGS.update(COLOR_TO_MASK_DISPLAY)
NODE_DISPLAY_NAME_MAPPINGS.update(LAZY_SWITCH_DISPLAY) NODE_DISPLAY_NAME_MAPPINGS.update(LAZY_SWITCH_DISPLAY)
NODE_DISPLAY_NAME_MAPPINGS.update(TEXT_TRANSLATOR_API_DISPLAY) NODE_DISPLAY_NAME_MAPPINGS.update(TEXT_TRANSLATOR_API_DISPLAY)
NODE_DISPLAY_NAME_MAPPINGS.update(GET_IMAGE_RANGE_DISPLAY)
NODE_CATEGORIES = { NODE_CATEGORIES = {
"UniversalToolkit": [ "UniversalToolkit": [
@@ -844,6 +866,7 @@ NODE_CATEGORIES = {
"LazySwitchKJ_UTK", "LazySwitchKJ_UTK",
"APIImageGenerator_UTK", "APIImageGenerator_UTK",
"TextTranslatorAPI_UTK", "TextTranslatorAPI_UTK",
"GetImageRangeFromBatch_UTK",
] ]
} }
+105
View File
@@ -0,0 +1,105 @@
import torch
from typing import Tuple, Optional
class GetImageRangeFromBatch_UTK:
"""
从批次中获取指定范围的图像或遮罩
支持从图像批次或遮罩批次中提取指定索引范围的元素
"""
RETURN_TYPES = ("IMAGE", "MASK")
RETURN_NAMES = ("image", "mask")
FUNCTION = "get_range_from_batch"
CATEGORY = "UniversalToolkit/tools"
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"start_index": ("INT", {
"default": 0,
"min": -1,
"max": 4096,
"step": 1,
"tooltip": "起始索引,-1表示从末尾开始"
}),
"num_frames": ("INT", {
"default": 1,
"min": 1,
"max": 4096,
"step": 1,
"tooltip": "要提取的帧数"
}),
},
"optional": {
"images": ("IMAGE", {
"tooltip": "输入的图像批次"
}),
"masks": ("MASK", {
"tooltip": "输入的遮罩批次"
}),
}
}
def get_range_from_batch(self, start_index: int, num_frames: int,
images: Optional[torch.Tensor] = None,
masks: Optional[torch.Tensor] = None) -> Tuple[Optional[torch.Tensor], Optional[torch.Tensor]]:
"""
从批次中获取指定范围的图像或遮罩
Args:
start_index: 起始索引,-1表示从末尾开始
num_frames: 要提取的帧数
images: 输入的图像批次 (可选)
masks: 输入的遮罩批次 (可选)
Returns:
Tuple[Optional[torch.Tensor], Optional[torch.Tensor]]: 提取的图像和遮罩
"""
chosen_images = None
chosen_masks = None
# 处理图像批次
if images is not None:
if start_index == -1:
# 从末尾开始计算起始索引
start_index = max(0, len(images) - num_frames)
if start_index < 0 or start_index >= len(images):
raise ValueError(f"图像起始索引 {start_index} 超出范围 [0, {len(images)-1}]")
end_index = min(start_index + num_frames, len(images))
chosen_images = images[start_index:end_index]
print(f"📸 从图像批次中提取: 索引 {start_index} 到 {end_index-1},共 {len(chosen_images)} 张图像")
# 处理遮罩批次
if masks is not None:
if start_index == -1:
# 从末尾开始计算起始索引
start_index = max(0, len(masks) - num_frames)
if start_index < 0 or start_index >= len(masks):
raise ValueError(f"遮罩起始索引 {start_index} 超出范围 [0, {len(masks)-1}]")
end_index = min(start_index + num_frames, len(masks))
chosen_masks = masks[start_index:end_index]
print(f"🎭 从遮罩批次中提取: 索引 {start_index} 到 {end_index-1},共 {len(chosen_masks)} 个遮罩")
# 检查是否至少有一个输入
if images is None and masks is None:
raise ValueError("至少需要提供图像或遮罩输入")
return (chosen_images, chosen_masks)
# 节点映射
NODE_CLASS_MAPPINGS = {
"GetImageRangeFromBatch_UTK": GetImageRangeFromBatch_UTK
}
NODE_DISPLAY_NAME_MAPPINGS = {
"GetImageRangeFromBatch_UTK": "Get Image or Mask Range From Batch (UTK)"
}
+1 -1
View File
@@ -1,7 +1,7 @@
[project] [project]
name = "universaltoolkit" name = "universaltoolkit"
description = "A comprehensive toolkit based on ComfyUI, providing image, mask, audio, and tools nodes, fully modular and v3 compatible." description = "A comprehensive toolkit based on ComfyUI, providing image, mask, audio, and tools nodes, fully modular and v3 compatible."
version = "1.4.3" version = "1.4.4"
license = {file = "LICENSE"} license = {file = "LICENSE"}
dependencies = [ dependencies = [
"torch>=1.9.0", "torch>=1.9.0",