Tetsuoo's custom nodes pack for ComfyUI
A collection of utility nodes designed to enhance your ComfyUI workflow with smart image loading, Krita integration, widget extraction, and more.
Category: TOO-Pack
cd ComfyUI/custom_nodes
git clone https://github.com/tetsuoo-online/Comfyui-TOO-Pack- ComfyUI (latest version recommended)
- Python 3.8+
- PyTorch
- Pillow (PIL)
- NumPy
| Node | Category | Description |
|---|---|---|
| Smart Image Loader | TOO-Pack/image |
Flexible image loader with multiple sources |
| Smart Image Saver | TOO-Pack/image |
Intelligent saver with flexible naming and metadata |
| Krita Bridge | TOO-Pack/image |
Auto-load images from Krita |
| Extract Widget From Node | TOO-Pack/utils |
Extract widget values from workflow nodes |
| Collection Categorizer | TOO-Pack/utils |
Categorize files with local LLM (Ollama) |
Click to expand full documentation
A flexible image loader that supports multiple input sources with priority order.
- Multiple sources: txt, direct path, directory, or direct image
- Smart priority order with configurable inputs
- Random selection with reproducible seed
- Multiple formats supported (PNG, JPG, JPEG, BMP, WEBP, TIFF)
- Returns file path of loaded image
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| seed | INT | Seed for reproducible random selection | 0 |
Optional Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| txt_path | STRING | Path to text file containing image paths | - |
| img_path | STRING | Direct path to an image file | - |
| img_directory | STRING | Path to directory containing images | - |
| image | IMAGE | Direct image input | - |
Outputs
| Parameter | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The loaded image as tensor |
| FILE_PATH | STRING | Path of loaded file ("external_input" or "none") |
The node loads images in this order (from highest to lowest priority):
- txt_path 📄 : Randomly selects a path from text file
- img_path 🖼 : Loads the specific image file
- img_directory 📁 : Randomly selects an image from directory
- image ⚡ : Uses the provided image input
Case 1: Text file with image list
# Content of image_list.txt:
# /path/to/image1.png
# /path/to/image2.jpg
# /path/to/image3.webp
txt_path = "/path/to/image_list.txt"
seed = 42 # ReproducibleCase 2: Direct path to image
img_path = "/path/to/specific/image.png"Case 3: Image directory
img_directory = "/path/to/images/"
seed = 123Case 4: Combination with priority
txt_path = "/path/to/list.txt" # Priority 1
img_path = "/path/to/fallback.png" # Priority 2 (if txt_path fails)
img_directory = "/path/to/backup/" # Priority 3 (if img_path fails)Text file format (txt_path)
The text file should contain one image path per line:
/home/user/images/photo1.png
/home/user/images/photo2.jpg
/home/user/images/photo3.webp
- Empty lines are ignored
- UTF-8 encoding supported
- A random path is selected using the seed
Seed handling
- seed = 0: Different random selection each run
- seed > 0: Identical selection with same parameters (reproducible)
FILE_PATH values
| Value | Description |
|---|---|
| Full path | Image loaded from txt_path, img_path or img_directory |
"external_input" |
Image provided via image parameter |
"none" |
No valid source found (error) |
Click to expand full documentation
An intelligent image saver that replaces the SAVE_IMG subgraph with flexible filename customization.
- Flexible naming: Customizable prefix, suffix, and separator
- Date tokens: YYYY, MM, DD, HH, mm, ss, timestamp support
- Smart metadata extraction: Auto-extract seed and model name from workflow
- Node targeting: Target nodes by class name or direct ID (#10)
- Multiple formats: WEBP (lossy/lossless), PNG, JPG/JPEG
- Metadata preservation: Saves prompt and workflow in EXIF/PNG info
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| images | IMAGE | Images to save | - |
| output_folder | STRING | Output folder (supports date tokens) | YYYY-MM-DD |
| prefix | STRING | Filename prefix (supports date tokens) | ComfyUI_YYYY-MM-DD_HHmmss |
| seed_node_name | STRING | Node containing seed (class name or #ID) | KSampler |
| model_node_name | STRING | Node containing model (class name or #ID) | CheckpointLoaderSimple |
| suffix | STRING | Filename suffix (supports date tokens) | "" |
| output_format | COMBO | Image format | webp |
| quality | INT | Compression quality (1-100) | 97 |
Outputs
| Parameter | Type | Description |
|---|---|---|
| images | IMAGE | Pass-through of input images |
| filepath | STRING | Path of the first saved file |
The node builds filenames in this order:
[prefix]_[seed]_[model_name]_[suffix].[format]
Elements are joined by the separator. Empty elements are skipped.
Case 1: Basic usage with date folder
output_folder = "YYYY-MM-DD" # → 2024-01-30/
prefix = "render_YYYYMMDD" # → render_20240130
seed_node_name = "KSampler"
model_node_name = "CheckpointLoaderSimple"Output: 2024-01-30/render_20240130_123456_mymodel.webp
Case 2: Target node by ID
seed_node_name = "#10" # Target node with ID 10
model_node_name = "#5" # Target node with ID 5Case 3: Disable seed or model
seed_node_name = "" # Don't include seed
model_node_name = "" # Don't include model
prefix = "my_render"
suffix = "HHmmss" # Add timestampOutput: my_render_143025.webp
All date tokens are replaced with current date/time values:
| Token | Description | Example |
|---|---|---|
YYYY |
Year (4 digits) | 2024 |
MM |
Month (2 digits) | 01 |
DD |
Day (2 digits) | 30 |
HH |
Hour 24h (2 digits) | 14 |
mm |
Minute (2 digits) | 30 |
ss |
Second (2 digits) | 25 |
timestamp |
Unix timestamp | 1706623825 |
By Class Name:
seed_node_name = "KSampler" # Finds any KSampler nodeBy Node ID:
seed_node_name = "#10" # Targets node with ID 10Click to expand full documentation
Automatically loads the latest image from the input/krita/ folder for seamless Krita integration.
- Automatic loading of latest image from krita folder
- Real-time detection of new files
- Auto-update during generation
- Alpha support: extracts alpha channel as mask
- Auto-create folder if doesn't exist
- No parameters - works directly
Required Parameters
No parameters required - The node works automatically!
Outputs
| Parameter | Type | Description |
|---|---|---|
| image | IMAGE | The loaded image (RGB) |
| mask | MASK | Mask extracted from alpha channel |
Working Directory
The node automatically loads from:
ComfyUI/input/krita/
If the folder doesn't exist, it's created automatically on first launch.
Export from Krita
- Open Krita
- Create or modify your image
- Export as PNG:
File > Export - Destination:
ComfyUI/input/krita/filename.png - The node automatically detects the new file
Recommended Workflow
Krita → Export PNG → ComfyUI/input/krita/ → Krita Bridge → [your workflow]
Case 1: Simple loading
# No configuration needed
# Node automatically loads latest imageCase 2: Using alpha mask
# Connect 'mask' to a mask node (Mask Composite, etc.)
# Krita image's alpha channel becomes usable maskCase 3: Iterative Krita ↔ ComfyUI workflow
1. Draw in Krita
2. Export → input/krita/sketch.png
3. ComfyUI detects and generates
4. Get result
5. Refine in Krita
6. Re-export → Node loads new version
Case 4: Inpainting with Krita mask
# Workflow:
# Krita Bridge (image + mask) → Inpaint Model → VAE Decode
# Krita's alpha mask defines inpainting areaFile Detection
The node:
- Scans
input/krita/folder for all.pngfiles - Finds file with most recent modification
- Compares timestamp with last loaded file
- Reloads if change detected
Alpha Channel Handling
RGBA image (with transparency):
- RGB channels →
imageoutput - Alpha channel →
maskoutput (0-1 values)
RGB image (no transparency):
- RGB →
imageoutput - Uniform white mask →
maskoutput
Automatic Update
The IS_CHANGED function returns current timestamp, forcing ComfyUI to:
- Re-evaluate node on every execution
- Detect new files in real-time
- Update image automatically
Krita Configuration
-
Set default export folder
Settings > Configure Krita > General- Set default folder:
ComfyUI/input/krita/
-
Keyboard shortcut for quick export
Settings > Configure Krita > Keyboard Shortcuts- Assign key to
Export - Example:
Ctrl+Shift+E
-
Export format
- Format: PNG
- Compression: as preferred
- Important: Enable "Save alpha channel" if using mask
Optimal Workflow
┌─────────┐ Export PNG ┌──────────────┐
│ Krita │ ───────────────> │ input/krita/ │
└─────────┘ └──────────────┘
│
▼
┌──────────────┐
│ Krita Bridge │
└──────────────┘
│
┌────────────────┴────────────────┐
▼ ▼
┌────────┐ ┌──────┐
│ image │ │ mask │
└────────┘ └──────┘
Click to expand full documentation
Extracts specific widget values from any node in the ComfyUI workflow.
- Targeted extraction of specific widgets by name
- Compatible with all ComfyUI nodes
- Multiple extraction: extract several widgets at once
- Auto mode: extracts all widgets if none specified
- Smart handling of dictionaries and nested values
- "on" filter: ignores disabled widgets
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| node_name | STRING | Node type name to target (e.g., "Power Lora Loader") | Power Lora Loader |
| widget_names | STRING | Widget names to extract (comma-separated) | lora_name, strength_model |
Hidden Parameters
| Parameter | Type | Description |
|---|---|---|
| extra_pnginfo | EXTRA_PNGINFO | Workflow PNG metadata |
| prompt | PROMPT | Current workflow data |
| unique_id | UNIQUE_ID | Node unique ID |
Outputs
| Parameter | Type | Description |
|---|---|---|
| STRING | STRING | Extracted values (one per line, separated by \n) |
Case 1: Extract specific widgets from Lora Loader
node_name = "Power Lora Loader"
widget_names = "lora_name, strength_model"Output:
my_lora_v1.safetensors
0.85
Case 2: Extract multiple parameters from KSampler
node_name = "KSampler"
widget_names = "seed, steps, cfg"Output:
123456789
20
7.5
Case 3: Extract all widgets (auto mode)
node_name = "CheckpointLoaderSimple"
widget_names = "" # Empty = extract allCase 4: Extract from multiple nodes of same type
node_name = "Power Lora Loader"
widget_names = "lora_name"Output (if 3 Lora Loaders in workflow):
lora1.safetensors
lora2.safetensors
lora3.safetensors
Node search
The node performs a case-insensitive search on node_name:
"power lora"will find"Power Lora Loader""ksampler"will find"KSampler"and"KSamplerAdvanced"
widget_names format
Widget names must be comma-separated:
"widget1, widget2, widget3"Spaces are automatically stripped.
Nested values handling
The node intelligently handles nested dictionaries:
Simple structure:
{
"lora_name": "my_lora.safetensors",
"strength_model": 0.85
}Nested structure (Power Lora Loader):
{
"loras": {
"on": true,
"lora_name": "my_lora.safetensors",
"strength_model": 0.85
}
}The node automatically extracts values from both structures.
"on" filter
If a dictionary contains "on": false, its values are ignored.
1. Extract prompts from workflow
node_name = "CLIPTextEncode"
widget_names = "text"2. Retrieve used seeds
node_name = "KSampler"
widget_names = "seed"3. List all loaded models
node_name = "CheckpointLoader"
widget_names = "ckpt_name"4. Extract control parameters
node_name = "ControlNetLoader"
widget_names = "control_net_name, strength"Click to expand full documentation
A ComfyUI node that automatically scans your folders and categorizes content with a local LLM (Ollama).
- Automatic scanning of folders (video files, archives, documents)
- Smart categorization via local LLM (Ollama)
- Recursive scanning of subfolders (optional)
- Reproducible seed for identical results
- Custom Ollama models supported
- Auto-save JSON output
- Compatible with Collection Manager
- 100% local - no external APIs
Main Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| ollama_model | COMBO | LLM model to use (or "custom") | qwen2.5:7b |
| custom_ollama_model | STRING | Model name if "custom" selected | - |
| folder_path | STRING | Path to folder to scan | - |
| scan_subfolders | BOOLEAN | Recursively scan subfolders | False |
| save_json | BOOLEAN | Auto-save JSON output | True |
| collection_title | STRING | Collection title | Ma Collection |
| content_type | COMBO | Content type (or "custom") | films |
Optional Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| custom_type_name | STRING | Type name if "custom" selected | - |
| custom_categories | STRING | Custom categorization criteria (multiline) | (empty = LLM decides) |
| seed | INT | Seed for reproducible results | 0 (random) |
Outputs
| Parameter | Type | Description |
|---|---|---|
| json_output | STRING | The complete collection JSON |
| summary | STRING | Categorization summary |
Case 1: Movies with automatic categories
content_type = "films"
custom_categories = "" # Empty
# LLM decides categories (Genre, Era, etc.)Case 2: TV Series with custom criteria
content_type = "series"
custom_categories = "Genre, Year, Studio"
# LLM categorizes by these criteriaCase 3: Custom type
content_type = "custom"
custom_type_name = "Documentaries"
custom_categories = "Theme, Duration"Case 4: Custom model
ollama_model = "custom"
custom_ollama_model = "mistral:7b"Case 5: Reproducible results
seed = 42
# Always same result with same parametersRequirements
-
Ollama installed and running
# Download: https://ollama.ai ollama --version -
Python requests (for local HTTP API)
pip install requests --break-system-packages
-
At least one LLM model
ollama pull qwen2.5:7b
Videos
.mp4, .mkv, .avi, .mov, .wmv, .flv
Archives
.cbz, .cbr, .zip, .rar
Documents
.epub, .pdf, .mobi
Folders
Subfolders are treated as individual items (unless scan_subfolders is enabled)
| Model | Size | Speed | Quality | Usage |
|---|---|---|---|---|
| qwen2.5:7b | 7B | ⚡⚡⚡ | ⭐⭐⭐⭐ | Recommended |
| gemma3:12b | 12B | ⚡⚡ | ⭐⭐⭐⭐⭐ | Best quality |
| llama3.1:8b | 8B | ⚡⚡⚡ | ⭐⭐⭐⭐ | Very reliable |
| gemma3:4b | 4B | ⚡⚡⚡⚡ | ⭐⭐⭐ | Fast |
{
"title": "My Collection",
"icon": "🎬",
"type": "Films",
"filename": "films.json",
"categories": [
{
"id": 1,
"name": "Science Fiction",
"subcategories": [],
"games": ["Blade Runner", "The Matrix"]
},
{
"id": 2,
"name": "Comedy",
"subcategories": [],
"games": ["Superbad", "The Hangover"]
}
]
}- Extract Widget From Node : aiming at nodes using name, title or ID
MIT License
Tetsuoo
- Claude AI ❤ - AI assistant extraordinaire
- ComfyUI - Amazing node-based interface
- Ollama - Local LLM runtime
- Krita - Open-source digital painting software