Add files via upload

This commit is contained in:
mango-rgb
2025-01-20 23:02:45 +08:00
committed by GitHub
parent a36d21bf73
commit d2e88ec181
5 changed files with 350 additions and 2 deletions
+271
View File
@@ -0,0 +1,271 @@
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": "随机文件 🥭",
}
+44 -2
View File
@@ -1,2 +1,44 @@
# ComfyUI-Mango-Random-node
comfyui Random read node, can specify the directory, random or sequential read image, text and video content
# 🥭 Mango Random Nodes 🥭
Welcome to **Comfyui Mango Random Nodes**! 🚀 This is a random file node tool designed for ComfyUI, making your workflow more flexible and interesting. Whether for creative projects or daily use, our tools help you easily access random files and images.
## Included Nodes 🌟
- 🎲 **Random File Path**
Randomly selects a file from a specified directory and returns the file path as a string.
- 🖼️ **Random Image Path**
Gets images and their corresponding text content (with the same filename) from a specified folder. Supports two modes:
- Sequential Cycle: Outputs files in order by filename
- Fully Random: Randomly selects and outputs images
- 🎬 **Random Video Path**
Gets videos and their corresponding text content (with the same filename) from a specified folder. Supports two modes:
- Sequential Cycle: Outputs files in order by filename
- Fully Random: Randomly selects and outputs videos
## Installation 🛠️
### Method 1: Clone Repository to `custom_nodes` Folder
1. **Clone Repository:**
Open Command Prompt or PowerShell and run:
```bash
git clone https://github.com/mango-rgb/ComfyUI-Mango-Random-node <path/to/comfyui/custom_nodes>
```
Replace `path/to/comfyui` with your actual ComfyUI installation path.
2. **Restart ComfyUI:**
Restart the ComfyUI server to load the new nodes.
### Method 2: Install via ComfyUI Manager
1. **Open ComfyUI Manager**
2. **Search for** `Mango Random Nodes`
3. **Install Nodes:**
Click the `Install` button to install the nodes.
4. **Restart ComfyUI:**
Restart the ComfyUI server after installation.
+20
View File
@@ -0,0 +1,20 @@
# 从当前包的 Mango_random_nodes 模块导入节点相关的映射字典
from .Mango_random_nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
import random
# 定义一个包含有趣的技术相关随机提示语的列表
tech_rambling = [
"Zap zap zoom!", "Sproing-a-ling!", "Flux capacitor charged!", "Circuit party started!",
"Electrons dancing!", "Voltage va-va-voom!", "Capacitor doing the cha-cha!", "Resistor raving!"
]
# 打印带颜色的欢迎信息,使用随机的技术提示语
print(f"\033[1;34m[Mango Suite]: 🥭🥭🥭 \033[96m\033[3m{random.choice(tech_rambling)}\033[0m 🥭🥭🥭")
# 打印已激活的节点数量信息
print(f"\033[1;34m[Mango Suite]:\033[0m Activated \033[96m{len(NODE_CLASS_MAPPINGS)}\033[0m file nodes.")
# 定义此包可以导出的名称列表
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
# 定义web目录的路径常量
WEB_DIRECTORY = "./web"
+13
View File
@@ -0,0 +1,13 @@
[project]
name = "comfyui-mango-random"
description = "🥭 Mango Random Nodes - A collection of random file selection nodes with image mask support"
version = "1.0.0"
license = {file = "LICENSE"}
[project.urls]
Repository = "https://github.com/mango-rgb/ComfyUI-Mango-Random-node"
[tool.comfy]
PublisherId = "mango-rgb"
DisplayName = "ComfyUI-Mango-Random"
Icon = "🥭"
+2
View File
@@ -0,0 +1,2 @@
opencv-python
imageio-ffmpeg