7.4 KiB
7.4 KiB
Documentation
- Class name: WAS_Load_Image_Batch
- Category: WAS Suite/IO
- Output node: False
- Repo Ref: https://github.com/WASasquatch/was-node-suite-comfyui
WAS_Load_Image_Batch 节点旨在高效地加载和管理图像文件批次。它提供以不同模式加载图像的功能,如单张图像、增量图像或随机选择。该节点确保图像正确定向,并且在需要时可以处理 RGBA 到 RGB 的转换。它还能够根据指定去除文件名中的文件扩展名。
Input types
Required
- path
- 'path' 参数指定了图像文件所在的目录路径。这对于节点定位和访问所需处理的图像文件至关重要。
- Comfy dtype: STRING
- Python dtype: str
Optional
- pattern
- 'pattern' 参数用于根据特定模式过滤图像文件。它对于在指定目录内选择符合给定标准的图像子集很重要。
- Comfy dtype: STRING
- Python dtype: str
- index
- 'index' 参数是一个整数,表示要加载的批次中图像的具体位置。当模式设置为 'single_image' 时,它在确定要检索的确切图像时起着重要作用。
- Comfy dtype: INT
- Python dtype: int
- mode
- 'mode' 参数确定加载图像的方法。它可以是 'single_image' 用于加载特定图像,'incremental_image' 用于顺序访问,或 'random' 用于随机选择。
- Comfy dtype: COMBO['single_image', 'incremental_image', 'random']
- Python dtype: str
- label
- 'label' 参数是一个字符串,用于标识和分类图像批次。它有助于在节点操作中组织和跟踪不同的图像集。
- Comfy dtype: STRING
- Python dtype: str
- allow_RGBA_output
- 'allow_RGBA_output' 参数决定是否允许输出图像具有 RGBA 通道。如果设置为 'false',则节点将图像转换为 RGB。
- Comfy dtype: COMBO['false', 'true']
- Python dtype: str
- filename_text_extension
- 'filename_text_extension' 参数指示是否在文件名文本输出中包含文件扩展名。在不需要文件扩展名的文件名中,它很有用。
- Comfy dtype: COMBO['true', 'false']
- Python dtype: str
Output types
- image
- 'image' 输出提供了指定批次中加载的图像。它是节点功能内图像处理任务的主要输出。
- Comfy dtype: IMAGE
- Python dtype: PIL.Image.Image
- filename_text
- 'filename_text' 输出返回加载的图像文件的名称,可以用于参考或在节点之外进行进一步处理。
- Comfy dtype: STRING
- Python dtype: str
Usage tips
- Infra type: CPU
Source code
class WAS_Load_Image_Batch:
def __init__(self):
self.HDB = WASDatabase(WAS_HISTORY_DATABASE)
@classmethod
def INPUT_TYPES(cls):
return {'required': {'mode': (['single_image', 'incremental_image', 'random'],), 'index': ('INT', {'default': 0, 'min': 0, 'max': 150000, 'step': 1}), 'label': ('STRING', {'default': 'Batch 001', 'multiline': False}), 'path': ('STRING', {'default': '', 'multiline': False}), 'pattern': ('STRING', {'default': '*', 'multiline': False}), 'allow_RGBA_output': (['false', 'true'],)}, 'optional': {'filename_text_extension': (['true', 'false'],)}}
RETURN_TYPES = ('IMAGE', TEXT_TYPE)
RETURN_NAMES = ('image', 'filename_text')
FUNCTION = 'load_batch_images'
CATEGORY = 'WAS Suite/IO'
def load_batch_images(self, path, pattern='*', index=0, mode='single_image', label='Batch 001', allow_RGBA_output='false', filename_text_extension='true'):
allow_RGBA_output = allow_RGBA_output == 'true'
if not os.path.exists(path):
return (None,)
fl = self.BatchImageLoader(path, label, pattern)
new_paths = fl.image_paths
if mode == 'single_image':
(image, filename) = fl.get_image_by_id(index)
if image == None:
cstr(f'No valid image was found for the inded `{index}`').error.print()
return (None, None)
elif mode == 'incremental_image':
(image, filename) = fl.get_next_image()
if image == None:
cstr(f'No valid image was found for the next ID. Did you remove images from the source directory?').error.print()
return (None, None)
else:
newindex = int(random.random() * len(fl.image_paths))
(image, filename) = fl.get_image_by_id(newindex)
if image == None:
cstr(f'No valid image was found for the next ID. Did you remove images from the source directory?').error.print()
return (None, None)
update_history_images(new_paths)
if not allow_RGBA_output:
image = image.convert('RGB')
if filename_text_extension == 'false':
filename = os.path.splitext(filename)[0]
return (pil2tensor(image), filename)
class BatchImageLoader:
def __init__(self, directory_path, label, pattern):
self.WDB = WDB
self.image_paths = []
self.load_images(directory_path, pattern)
self.image_paths.sort()
stored_directory_path = self.WDB.get('Batch Paths', label)
stored_pattern = self.WDB.get('Batch Patterns', label)
if stored_directory_path != directory_path or stored_pattern != pattern:
self.index = 0
self.WDB.insert('Batch Counters', label, 0)
self.WDB.insert('Batch Paths', label, directory_path)
self.WDB.insert('Batch Patterns', label, pattern)
else:
self.index = self.WDB.get('Batch Counters', label)
self.label = label
def load_images(self, directory_path, pattern):
for file_name in glob.glob(os.path.join(glob.escape(directory_path), pattern), recursive=True):
if file_name.lower().endswith(ALLOWED_EXT):
abs_file_path = os.path.abspath(file_name)
self.image_paths.append(abs_file_path)
def get_image_by_id(self, image_id):
if image_id < 0 or image_id >= len(self.image_paths):
cstr(f'Invalid image index `{image_id}`').error.print()
return
i = Image.open(self.image_paths[image_id])
i = ImageOps.exif_transpose(i)
return (i, os.path.basename(self.image_paths[image_id]))
def get_next_image(self):
if self.index >= len(self.image_paths):
self.index = 0
image_path = self.image_paths[self.index]
self.index += 1
if self.index == len(self.image_paths):
self.index = 0
cstr(f'{cstr.color.YELLOW}{self.label}{cstr.color.END} Index: {self.index}').msg.print()
self.WDB.insert('Batch Counters', self.label, self.index)
i = Image.open(image_path)
i = ImageOps.exif_transpose(i)
return (i, os.path.basename(image_path))
def get_current_image(self):
if self.index >= len(self.image_paths):
self.index = 0
image_path = self.image_paths[self.index]
return os.path.basename(image_path)
@classmethod
def IS_CHANGED(cls, **kwargs):
if kwargs['mode'] != 'single_image':
return float('NaN')
else:
fl = WAS_Load_Image_Batch.BatchImageLoader(kwargs['path'], kwargs['label'], kwargs['pattern'])
filename = fl.get_current_image()
image = os.path.join(kwargs['path'], filename)
sha = get_sha256(image)
return sha