Files
mango-rgb-ComfyUI-Mango-Ran…/Mango_random_nodes.py
T
2025-01-20 23:02:45 +08:00

272 lines
8.2 KiB
Python

import os
import random
import torch
from PIL import Image, ImageOps
import numpy as np
import cv2
import time
class RandomFilePathNode:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"directory_path": ("STRING", {"default": ""}),
},
}
@classmethod
def IS_CHANGED(cls, **kwargs):
return float("NaN")
RETURN_TYPES = ("STRING",)
FUNCTION = "get_random_file_path"
CATEGORY = "🥭 芒果节点/文件"
def get_random_file_path(self, directory_path: str) -> str:
if not os.path.isdir(directory_path):
raise NotADirectoryError(
f"'{directory_path}' is not a valid directory path.")
files = []
# Walk through the directory tree
for root, dirs, files_in_dir in os.walk(directory_path):
for file_name in files_in_dir:
# Build full path to the file
full_file_path = os.path.join(root, file_name)
# Check if the file has a valid extension
files.append(full_file_path)
if not files:
raise FileNotFoundError(
f"No files found in directory: {directory_path}")
path = random.choice(files)
return (path,)
class RandomImagePathNode:
def __init__(self):
self.current_seed = 0
self.current_index = 0
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"directory_path": ("STRING", {"default": ""}),
"sort_mode": (["完全随机" , "顺序循环"],),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
},
}
@classmethod
def IS_CHANGED(cls, **kwargs):
return float("NaN")
RETURN_TYPES = ("IMAGE", "MASK", "STRING")
RETURN_NAMES = ("image", "mask", "text_content")
FUNCTION = "get_random_image_path"
CATEGORY = "🥭 芒果节点/文件"
def get_random_image_path(self, directory_path, sort_mode, seed) -> tuple:
if not os.path.isdir(directory_path):
raise NotADirectoryError(
f"'{directory_path}' is not a valid directory path.")
valid_extensions = (".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".webp")
files = []
for root, dirs, files_in_dir in os.walk(directory_path):
for file_name in files_in_dir:
full_file_path = os.path.join(root, file_name)
if file_name.lower().endswith(valid_extensions):
files.append(full_file_path)
if not files:
raise FileNotFoundError(
f"No image files found in directory: {directory_path}")
# 根据排序模式选择文件
elif sort_mode == "顺序循环":
files.sort(key=lambda x: os.path.basename(x).lower())
path = files[self.current_index]
self.current_index = (self.current_index + 1) % len(files)
else: # 完全随机模式
path = random.choice(files)
image = Image.open(path)
image = ImageOps.exif_transpose(image)
# 处理alpha通道
if image.mode == 'RGBA':
rgb = image.convert('RGB')
alpha = image.split()[3]
image = np.array(rgb).astype(np.float32) / 255.0
image = torch.from_numpy(image)[None,]
mask = np.array(alpha).astype(np.float32) / 255.0
mask = torch.from_numpy(mask)[None,]
else:
image = image.convert('RGB')
image = np.array(image).astype(np.float32) / 255.0
image = torch.from_numpy(image)[None,]
mask = torch.ones((1, image.shape[2], image.shape[3]), dtype=torch.float32)
# 获取对应的txt文件内容
txt_path = os.path.splitext(path)[0] + '.txt'
text_content = ""
try:
if os.path.exists(txt_path):
with open(txt_path, 'r', encoding='utf-8') as f:
text_content = f.read().strip()
else:
text_content = "No corresponding text file found"
except Exception as e:
text_content = f"Error reading text file: {str(e)}"
return (image, mask, text_content)
video_extensions = ('webm', 'mp4', 'mkv', 'gif')
class RandomVideoPathNode:
def __init__(self):
self.current_seed = 0
self.current_index = 0
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"directory_path": ("STRING", {"default": ""}),
"sort_mode": (["完全随机", "顺序循环"],),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
},
}
@classmethod
def IS_CHANGED(cls, **kwargs):
return float("NaN")
RETURN_TYPES = ("IMAGE", "STRING", "STRING")
RETURN_NAMES = ("images", "path", "text_content")
FUNCTION = "get_random_video_path"
CATEGORY = "🥭 芒果节点/文件"
def get_random_video_path(self, directory_path, sort_mode, seed) -> tuple:
if not os.path.isdir(directory_path):
raise NotADirectoryError(
f"'{directory_path}' is not a valid directory path.")
files = []
for root, dirs, files_in_dir in os.walk(directory_path):
for file_name in files_in_dir:
full_file_path = os.path.join(root, file_name)
if file_name.lower().endswith(video_extensions):
files.append(full_file_path)
if not files:
raise FileNotFoundError(
f"No video files found in directory: {directory_path}")
# 根据排序模式选择文件
if sort_mode == "顺序循环":
files.sort(key=lambda x: os.path.basename(x).lower())
path = files[self.current_index]
self.current_index = (self.current_index + 1) % len(files)
else: # 完全随机模式
random.seed(seed)
path = random.choice(files)
images = FrameGenerator(path)
# 获取对应的txt文件内容
txt_path = os.path.splitext(path)[0] + '.txt'
text_content = ""
try:
if os.path.exists(txt_path):
with open(txt_path, 'r', encoding='utf-8') as f:
text_content = f.read().strip()
else:
text_content = "No corresponding text file found"
except Exception as e:
text_content = f"Error reading text file: {str(e)}"
return (images, path, text_content)
def get_video_frames(video_path):
video_cap = cv2.VideoCapture(video_path)
if not video_cap.isOpened():
raise ValueError(f"Could not open video file: {video_path}")
frames = []
while True:
ret, frame = video_cap.read()
if not ret:
break
frames.append(frame)
video_cap.release()
return frames
class FrameGenerator:
def __init__(self, video_path):
self.video_path = video_path
self.frames = self._load_frames()
def _load_frames(self):
video_cap = cv2.VideoCapture(self.video_path)
if not video_cap.isOpened():
raise ValueError(f"Could not open video file: {self.video_path}")
frames = []
while True:
ret, frame = video_cap.read()
if not ret:
break
# Convert frame from BGR to RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# Convert frame to a torch tensor and normalize it
frame_tensor = torch.from_numpy(frame).float() / 255.0
frames.append(frame_tensor)
video_cap.release()
return frames
def __len__(self):
return len(self.frames)
def __getitem__(self, index):
return self.frames[index]
def __iter__(self):
return iter(self.frames)
NODE_CLASS_MAPPINGS = {
"Random Video Path": RandomVideoPathNode,
"Random Image Path": RandomImagePathNode,
"Random File Path": RandomFilePathNode,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"Random Video Path": "随机视频 🥭",
"Random Image Path": "随机图片 🥭",
"Random File Path": "随机文件 🥭",
}