Tetsuoo's custom nodes pack for ComfyUI
A collection of utility nodes designed to enhance your ComfyUI workflow with smart image loading, metadata management, widget extraction, Krita integration 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 |
|---|---|---|
| Simple Image Loader | TOO-Pack/image |
Simple image loader with a dynamic preview, no need to start the workflow :) |
| 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 |
| Smart Image Saver (Advanced) | TOO-Pack/image |
Advanced saver with dynamic naming and A1111/Civitai metadata |
| TOO Crop Image | TOO-Pack/image |
Interactive cropping tool |
| TOO lmage Metadata | TOO-Pack/image |
Metadata editing |
| 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) |
| Time Converter | TOO-Pack/utils |
Quick tool for converting seconds/min/hours |
Click to expand full documentation
An image loader that show instant preview with any path. You're no longer limited to ComfyUI/input folder.
The idea was inspired by the Load Image (Path) node from comfyui-VideoHelperSuite, with a few more features.
- πΌοΈ Image input via path img_path will work with any path on your computer, it doesn't have to be in ComfyUI folders
- πΌοΈ Image Preview Instant preview, no need to start the workflow. Can be toggled on/off
- π A1111/Civitai metadata extraction
- π ComfyUI workflow extraction
- Returns file path of loaded image
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| img_path | STRING | Direct path to an image file | - |
Outputs
| Parameter | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The loaded image (from image input or widgets) |
| FILE_PATH | STRING | Path of loaded file |
| metadata | METADATA | A1111/Civitai metadata extracted from file |
| workflow | WORKFLOW | ComfyUI workflow extracted from file |
Click to expand full documentation
A flexible image loader that supports multiple input sources with metadata extraction.
- 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)
- πΌοΈ Image Preview
- π A1111/Civitai metadata extraction
- π ComfyUI workflow extraction
- Returns file path of loaded image
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| seed | INT | Seed for reproducible random selection | 0 |
| img_dir_level | INT | Subdirectory depth: -1=all, 0=current, 1-10=levels | 0 |
| show_preview | BOOLEAN | Show image preview in the node | True |
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 (priority for IMAGE output) | - |
Outputs
| Parameter | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The loaded image (from image input or widgets) |
| FILE_PATH | STRING | Path of loaded file |
| metadata | METADATA | A1111/Civitai metadata extracted from file |
| workflow | WORKFLOW | ComfyUI workflow extracted from file |
The node loads images in this order (from highest to lowest priority):
- image β‘ : Uses the provided image input (for passing images only - does not load metadata or workflow)
- txt_path π : Randomly selects a path from text file
- img_path πΌ : Loads the specific image file
- img_directory π : Randomly selects an image from directory
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 |
Minutes (2 digits) | 30 |
ss |
Seconds (2 digits) | 25 |
timestamp |
Unix timestamp | 1706626225 |
By class name:
seed_node_name = "KSampler"
model_node_name = "CheckpointLoaderSimple"By ID:
seed_node_name = "#10" # Targets node with ID 10Click to expand full documentation
Node for saving images with advanced file naming and A1111/Civitai Auto V3 compatible metadata.
Category: TOO-Pack/image
- Dynamic file naming with workflow extraction
- Metadata injection/editing
- Support for 3 universal inputs (
any1,any2,any3) - Automatic model and LoRA extraction with hash calculation
- Targeted text replacement
- Customizable date formatting
- A1111/Civitai compatible metadata
- Output formats: PNG, JPG, WebP
| Parameter | Type | Description |
|---|---|---|
images |
IMAGE | Images to save (required) |
metadata |
METADATA | Optional metadata |
workflow |
WORKFLOW | Workflow to embed |
any1 |
* | Universal input 1 |
any2 |
* | Universal input 2 |
any3 |
* | Universal input 3 |
| Output | Type | Description |
|---|---|---|
images |
IMAGE | Images passthrough |
filepath |
STRING | Saved file path |
Create custom data fields for metadata and naming.
Value formats:
- Static text:
"my_text" - Widget extraction:
#123:widget_name(node ID) orClassName:widget_name - Any input:
[any1],[any2],[any3]
Example:
name: positive
value: #45:text
name: model_used
value: [any1]
Format dates for naming.
- date1: Date format (e.g.
YYYY-MM-DD) - date2: Time format (e.g.
HHmmss) - date3: Custom format
Available tokens: YYYY, YY, MM, DD, HH, mm, ss, timestamp
Automatic model extraction.
Value: #123:ckpt_name or [any1]
The node automatically calculates:
- Model name (basename without extension)
- Model hash (first 10 characters of SHA256)
Automatic LoRA extraction with Civitai-compatible hash.
Add multiple loras:
- Lora 1:
#45:lora_nameor[any1] - Lora 2:
#67:lora_nameor[any2]
Multiline support: If [any1] contains:
lora1.safetensors
lora2.safetensors
β Both are parsed automatically
Replace text in fields before naming.
Target:
- Empty or
[any1]/[any2]/[any3]β Apply to all fields positiveβ Apply only to "positive" fieldmodelβ Apply only to model
Example:
target: positive
in: (masterpiece)
out:
β Removes "(masterpiece)" from positive prompt
Build filename with available elements.
Available fields:
output_folder: Output subfolderprefix: File prefixextra1,extra2,extra3: Additional fieldsmodel: Model namesuffix: File suffixseparator: Separator character (default:_)
Available sources:
- Empty (ignored)
[any1],[any2],[any3]: Universal inputs- Data field name:
positive,seed,steps, etc. model,loras: Extracted values%date1,%date2,%date3: Formatted dates
Naming example:
prefix: %date1
extra1: positive
model: model
suffix: seed
separator: _
β 2025-02-12_beautiful_landscape_MyModel_12345.webp
Output configuration.
- format:
png,jpg,webp - quality: 1-100 (for jpg/webp)
- save metadata: Include A1111 metadata
- embed workflow: Embed ComfyUI workflow (except JPG)
Configuration:
DATA:
- name: seed, value: #10:seed
MODEL:
- extract: KSampler:ckpt_name
NAMING:
- prefix: %date1
- model: model
- suffix: seed
- separator: _
Result: 2025-02-12_MyCheckpoint_8675309.webp
Workflow:
ExtractWidgetFromNode β any1 (TOO Smart Image Saver)
Configuration:
LORAS:
- lora 1: [any1]
NAMING:
- prefix: %date1
- extra1: loras
If any1 contains:
style_lora_v2.safetensors
quality_lora_v1.safetensors
Generated metadata:
Lora hashes: "style_lora_v2: a1b2c3d4e5f6, quality_lora_v1: f6e5d4c3b2a1"
Configuration:
TEXT REPLACE:
- target: positive
- in: (masterpiece, best quality)
- out:
NAMING:
- prefix: positive
If positive = "beautiful landscape, (masterpiece, best quality)"
β Filename: beautiful_landscape.webp
Use ExtractWidgetFromNode to retrieve all used LoRAs β connect to any1 β The node automatically calculates all hashes for Civitai compatibility.
Configure output_folder: model to automatically sort images by model used.
Create data fields for all important parameters (seed, steps, cfg, sampler, scheduler) β The node generates complete A1111 metadata readable by Civitai and Automatic1111.
Use any inputs to inject dynamic information from other nodes (tags, descriptions, scores, etc.).
- Data fields are flexible: create as many fields as needed
- [any1], [any2], [any3] accept any data type (converted to string)
- Multiline is supported for loras: one line = one lora
- LoRA hashes exclude safetensors metadata (Civitai AutoV3 compatible)
- Text replace applies to extracted values before filename construction
- Empty lines in data fields are automatically ignored
- The metadata input has priority over node data fields, unless data fields are explicitly set (enables metadata injection/editing)
Click to expand full documentation
Extracts specific widget values from any node in the ComfyUI workflow.
- Targeted extraction of specific widgets by name
- Multiple widgets supported (comma-separated)
- Multi-node support: Targets all nodes matching class name
- Direct ID targeting with
#IDsyntax - Intelligent parsing of nested structures
- "on" filter: Ignores disabled elements
Required Parameters
| Parameter | Type | Description | Default |
|---|---|---|---|
| node_name | STRING | Node class name or #ID to target |
- |
| widget_names | STRING | Widget name(s) to extract (comma-separated) | - |
Outputs
| Parameter | Type | Description |
|---|---|---|
| extracted_values | STRING | Extracted values (multiline if multiple) |
Case 1: Extract a single widget
node_name = "KSampler"
widget_names = "seed"Output: "12345"
Case 2: Extract multiple widgets
node_name = "CLIPTextEncode"
widget_names = "text, strength"Output:
beautiful landscape, masterpiece
0.85
Case 3: Target specific node by ID
node_name = "#10"
widget_names = "ckpt_name"Case 4: Extract from multiple matching nodes
node_name = "LoraLoader"
widget_names = "lora_name"Output (if 2 LoraLoader nodes exist):
style_lora.safetensors
detail_lora.safetensors
Node Targeting
The node supports two targeting modes:
-
By class name (e.g.,
"KSampler")- Finds all nodes of this class
- Extracts from all matching nodes
-
By ID (e.g.,
"#10")- Targets specific node with ID 10
- Only one node targeted
Widget Extraction
- Simple values:
"my_value" - Multiple values: Separated by newlines
- Comma support:
"widget1, widget2"extracts both
Nested Dictionary 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
Interactive tool for cropping your image before output.
If you use the image input then the cropping will apply to it. However the interactive preview works only with img_path input so you will need to use that. You can also use only img_path like you would with a Simple Image Loader
Click to expand full documentation
Editing tool for A1111/Civitai metadata.
Very straight forward, you will need TOO Simple Image Loader or TOO Smart Image Loader to input the metadata to modify. Any empty field will be ignored, the node will not erase any original metadata unless you specify something.
For the model field you might want to follow A1111/Civitai syntax [Model hash: <hash>, Model: modelName] -> Only 1 model can be input, as far as I know... Maybe something to investigate later x)
As for the loras, the syntax is [Lora hashes: "<lora1>:<hash>,<lora2>:<hash>,<lora....>:<hash>"] -> As many loras as necessary
Click 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
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
