diff --git a/README.md b/README.md index b7024ee..c3a24b0 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,33 @@ Combine prompt parts, convert lists to readable text, create metadata tags, buil +
+🔄 Text Replace - Replace specific text in a string + +**Category:** `DebugPadawan/Text` + +Replaces all occurrences of a specific substring within a text string. + +**📥 Inputs:** +- `text` *(String)*: The text to process +- `find` *(String)*: The substring to search for +- `replace` *(String)*: The string to replace it with + +**📤 Outputs:** +- `text` *(String)*: The modified text string + +**💡 Example:** +``` +Input: "A beautiful sunset over the ocean" +Find: "sunset" +Replace: "sunrise" +Output: "A beautiful sunrise over the ocean" +``` + +Useful for dynamically adjusting prompts, modifying paths, and cleaning up generated text. + +
+ --- ### 📦 Data Conversion @@ -209,6 +236,29 @@ Rate limit API calls, debug timing issues, control workflow execution speed, add --- +### 🖼️ Image Utilities + +
+📐 Image Info - Extract image tensor dimensions + +**Category:** `DebugPadawan/Image` + +Extracts the width, height, and batch size from a ComfyUI Image tensor. + +**📥 Inputs:** +- `image` *(Image)*: The image tensor to analyze + +**📤 Outputs:** +- `width` *(Integer)*: Image width in pixels +- `height` *(Integer)*: Image height in pixels +- `batch_size` *(Integer)*: Number of images in the batch + +Useful for dynamic resizing, conditional logic based on aspect ratio, or passing dimensions to other nodes. + +
+ +--- + ### 🔧 Utility Nodes
@@ -281,12 +331,13 @@ Data → Wait (2.0s) → Processing → Wait (1.0s) → Output | Category | Nodes | Purpose | |----------|-------|---------| -| **DebugPadawan/Text** | Text Splitter, Text Joiner | Text manipulation and processing | +| **DebugPadawan/Text** | Text Splitter, Text Joiner, Text Replace | Text manipulation and processing | | **DebugPadawan/JSON** | TextToJSON | Text to JSON conversion | | **DebugPadawan/Debug** | Debug Print | Debugging and monitoring | | **DebugPadawan/Timing** | Wait | Timing control and delays | | **DebugPadawan/Utilities** | List Info | Data analysis helpers | | **DebugPadawan/Logic** | Conditional String | Conditional operations | +| **DebugPadawan/Image** | Image Info | Image tensor analysis | --- diff --git a/__init__.py b/__init__.py index 1e15312..091abc0 100644 --- a/__init__.py +++ b/__init__.py @@ -11,6 +11,8 @@ from .nodes.timing import TIMING_NODE_CLASS_MAPPINGS as TIMING_NODES from .nodes.timing import TIMING_NODE_DISPLAY_NAME_MAPPINGS as TIMING_DISPLAY_NAMES from .nodes.json import NODE_CLASS_MAPPINGS as JSON_NODES from .nodes.json import NODE_DISPLAY_NAME_MAPPINGS as JSON_DISPLAY_NAMES +from .nodes.image import NODE_CLASS_MAPPINGS as IMAGE_NODES +from .nodes.image import NODE_DISPLAY_NAME_MAPPINGS as IMAGE_DISPLAY_NAMES # Combine all node mappings NODE_CLASS_MAPPINGS = { @@ -18,6 +20,7 @@ NODE_CLASS_MAPPINGS = { **UTILITY_NODES, **TIMING_NODES, **JSON_NODES, + **IMAGE_NODES, } NODE_DISPLAY_NAME_MAPPINGS = { @@ -25,6 +28,7 @@ NODE_DISPLAY_NAME_MAPPINGS = { **UTILITY_DISPLAY_NAMES, **TIMING_DISPLAY_NAMES, **JSON_DISPLAY_NAMES, + **IMAGE_DISPLAY_NAMES, } __all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] diff --git a/nodes/image.py b/nodes/image.py new file mode 100644 index 0000000..689857d --- /dev/null +++ b/nodes/image.py @@ -0,0 +1,37 @@ +class ImageInfo: + """ + Node for getting width, height, and batch size from an Image + """ + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "image": ("IMAGE",), + } + } + + RETURN_TYPES = ("INT", "INT", "INT") + RETURN_NAMES = ("width", "height", "batch_size") + + FUNCTION = "get_info" + CATEGORY = "DebugPadawan/Image" + + def get_info(self, image): + """ + Extract dimensions from a ComfyUI image tensor + ComfyUI images are formatted as [batch_size, height, width, channels] + """ + batch_size = image.shape[0] + height = image.shape[1] + width = image.shape[2] + + return (width, height, batch_size) + +NODE_CLASS_MAPPINGS = { + "DebugPadawan_ImageInfo": ImageInfo, +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "DebugPadawan_ImageInfo": "Image Info", +} diff --git a/nodes/text_processing.py b/nodes/text_processing.py index 7820f99..088ba52 100644 --- a/nodes/text_processing.py +++ b/nodes/text_processing.py @@ -38,24 +38,12 @@ class TextSplitter: def split_text(self, text, delimiter, strip_whitespace=True, remove_empty=True): """ Split text by delimiter and return list with count - - Args: - text (str): Input text to split - delimiter (str): Character(s) to split by - strip_whitespace (bool): Whether to strip whitespace from each item - remove_empty (bool): Whether to remove empty strings from result - - Returns: - tuple: (list of strings, count of items) """ - # Split the text result = text.split(delimiter) - # Strip whitespace if requested if strip_whitespace: result = [item.strip() for item in result] - # Remove empty strings if requested if remove_empty: result = [item for item in result if item] @@ -96,30 +84,48 @@ class TextJoiner: CATEGORY = "DebugPadawan/Text" def join_text(self, text_list, delimiter, prefix="", suffix=""): - """ - Join list of strings with delimiter - - Args: - text_list (list): List of strings to join - delimiter (str): String to join with - prefix (str): String to add at the beginning - suffix (str): String to add at the end - - Returns: - str: Joined string - """ - # Convert all items to strings str_list = [str(item) for item in text_list] - - # Join with delimiter result = delimiter.join(str_list) - - # Add prefix and suffix result = prefix + result + suffix - return (result,) +class TextReplace: + """ + Node for replacing specific text in a string + """ + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "text": ("STRING", { + "multiline": True, + "default": "A beautiful sunset over the ocean" + }), + "find": ("STRING", { + "multiline": False, + "default": "sunset" + }), + "replace": ("STRING", { + "multiline": False, + "default": "sunrise" + }), + } + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("text",) + + FUNCTION = "replace_text" + CATEGORY = "DebugPadawan/Text" + + def replace_text(self, text, find, replace): + if not find: + return (text,) + return (text.replace(find, replace),) + + class ListInfo: """ Node for getting information about a list @@ -140,15 +146,6 @@ class ListInfo: CATEGORY = "DebugPadawan/Utilities" def get_list_info(self, input_list): - """ - Get information about a list - - Args: - input_list (list): Input list to analyze - - Returns: - tuple: (count, first_item, last_item) - """ count = len(input_list) first_item = str(input_list[0]) if input_list else "" last_item = str(input_list[-1]) if input_list else "" @@ -156,16 +153,16 @@ class ListInfo: return (count, first_item, last_item) - - NODE_CLASS_MAPPINGS = { "DebugPadawan_TextSplitter": TextSplitter, "DebugPadawan_TextJoiner": TextJoiner, + "DebugPadawan_TextReplace": TextReplace, "DebugPadawan_ListInfo": ListInfo, } NODE_DISPLAY_NAME_MAPPINGS = { "DebugPadawan_TextSplitter": "Text Splitter", "DebugPadawan_TextJoiner": "Text Joiner", + "DebugPadawan_TextReplace": "Text Replace", "DebugPadawan_ListInfo": "List Info", -} \ No newline at end of file +}