diff --git a/nodes/image/FL_ImageSlicer.py b/nodes/image/FL_ImageSlicer.py index ed5fbb2..f77fd31 100644 --- a/nodes/image/FL_ImageSlicer.py +++ b/nodes/image/FL_ImageSlicer.py @@ -8,8 +8,8 @@ class FL_ImageSlicer: return { "required": { "image": ("IMAGE",), - "x_subdivisions": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1}), - "y_subdivisions": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1}), + "width_subdivisions": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1}), + "height_subdivisions": ("INT", {"default": 2, "min": 1, "max": 100, "step": 1}), }, } @@ -17,7 +17,7 @@ class FL_ImageSlicer: FUNCTION = "slice_image" CATEGORY = "🏵️Fill Nodes/Image" - def slice_image(self, image, x_subdivisions, y_subdivisions): + def slice_image(self, image, width_subdivisions, height_subdivisions): # Convert from torch tensor to PIL Image pil_image = tensor_to_pil(image) @@ -25,13 +25,13 @@ class FL_ImageSlicer: width, height = pil_image.size # Calculate slice dimensions - slice_width = width // x_subdivisions - slice_height = height // y_subdivisions + slice_width = width // width_subdivisions + slice_height = height // height_subdivisions # Slice the image slices = [] - for y in range(y_subdivisions): - for x in range(x_subdivisions): + for y in range(height_subdivisions): + for x in range(width_subdivisions): left = x * slice_width upper = y * slice_height right = left + slice_width diff --git a/nodes/image/FL_SaveImages.py b/nodes/image/FL_SaveImages.py index 0d00d32..afca817 100644 --- a/nodes/image/FL_SaveImages.py +++ b/nodes/image/FL_SaveImages.py @@ -1,4 +1,5 @@ import os +import re import torch from PIL import Image import numpy as np @@ -14,6 +15,7 @@ class FL_SaveImages: "folder_structure": ("STRING", {"default": "[]"}), "file_name_template": ("STRING", {"default": "image_{index}.png"}), "start_index": ("INT", {"default": 1, "min": 0, "max": 1000000}), + "auto_increment": ("BOOLEAN", {"default": True}), }, "optional": { "metadata": ("STRING", {"default": ""}), @@ -25,24 +27,28 @@ class FL_SaveImages: OUTPUT_NODE = True CATEGORY = "🏵️Fill Nodes/Image" - def save_images(self, images, base_directory, folder_structure, file_name_template, start_index, metadata=""): + def save_images(self, images, base_directory, folder_structure, file_name_template, start_index, auto_increment=True, metadata=""): saved_paths = [] folder_structure = json.loads(folder_structure) # Ensure base directory exists os.makedirs(base_directory, exist_ok=True) + # Create the full folder path based on the folder structure + full_folder_path = self.create_folder_path(base_directory, folder_structure) + os.makedirs(full_folder_path, exist_ok=True) + batch_size = len(images) has_index_placeholder = "{index}" in file_name_template + # If auto_increment is enabled, find the next available index + if auto_increment and has_index_placeholder: + start_index = self.find_next_index(full_folder_path, file_name_template, start_index) + for i, image in enumerate(images): # Convert the image tensor to a PIL Image img = Image.fromarray((image.cpu().numpy() * 255).astype(np.uint8)) - # Create the full folder path based on the folder structure - full_folder_path = self.create_folder_path(base_directory, folder_structure) - os.makedirs(full_folder_path, exist_ok=True) - # Determine the filename based on batch size and placeholder if batch_size > 1: # For batches, always use an index @@ -82,6 +88,26 @@ class FL_SaveImages: return (", ".join(saved_paths),) + def find_next_index(self, folder_path, file_name_template, min_index): + """Find the next available index by checking existing files in the folder.""" + if not os.path.exists(folder_path): + return min_index + + # Build a regex pattern from the template to extract existing indices + # Escape special regex chars, then replace {index} with a capture group + pattern_str = re.escape(file_name_template).replace(r"\{index\}", r"(\d+)") + pattern = re.compile(f"^{pattern_str}$") + + max_found = min_index - 1 + for filename in os.listdir(folder_path): + match = pattern.match(filename) + if match: + index = int(match.group(1)) + if index > max_found: + max_found = index + + return max_found + 1 + def create_folder_path(self, base_directory, folder_structure): path = base_directory for folder in folder_structure: diff --git a/pyproject.toml b/pyproject.toml index d40d6e8..22a2c8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_fill-nodes" description = "Fill-Nodes is a versatile collection of custom nodes for ComfyUI that extends functionality across multiple domains. Features include advanced image processing (pixelation, slicing, masking), visual effects generation (glitch, halftone, pixel art), comprehensive file handling (PDF creation/extraction, Google Drive integration), AI model interfaces (GPT, DALL-E, Hugging Face), utility nodes for workflow enhancement, and specialized tools for video processing, captioning, and batch operations. The pack provides both practical workflow solutions and creative tools within a unified node collection." -version = "2.1.6" +version = "2.1.7" license = "LICENSE" dependencies = ["diffusers", "librosa", "sounddevice", "glitch_this", "PyOpenGL", "glfw", "scipy>=1.13.1", "requests", "aiohttp", "moviepy", "matplotlib", "reportlab", "openai", "PyPDF2", "pdf2image", "PyMuPDF", "reportlab", "PyPDF2", "ollama", "kornia", "opencv-python", "gdown", "open_clip_torch", "google-genai"]