ComfyUI Extension: ComfyUI-JK-TextTools
Run ComfyUI workflows without the setup
No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.
Text and data manipulation nodes for ComfyUI, with emphasis on JSON processing, detection workflows, and bbox visualization.
Looking for a different extension?
Custom Nodes (14)
README
ComfyUI-JK-TextTools
Text and data manipulation nodes for ComfyUI, with emphasis on JSON processing, detection workflows, and bbox visualization.
Features
- Text Manipulation: Split, join, and index delimited strings with type casting
- JSON Processing: Format and query JSON data with wildcard filtering
- Detection Workflows: Extract and visualize bounding boxes from detection results
- Mask Generation: Convert bboxes and segmentations to masks for image processing
- Segmentation Support: Process SEGS format from SAM3 with filtering and union capabilities
- Mask to BBox Conversion: Convert masks back to bounding boxes for chaining workflows
Installation
Via ComfyUI Manager (Recommended)
(When published)
- Open ComfyUI Manager
- Search for "JK-TextTools"
- Click Install
Manual Installation
-
Navigate to your ComfyUI custom_nodes directory:
cd ComfyUI/custom_nodes -
Clone this repository:
git clone https://github.com/Nakamura2828/ComfyUI-JK-TextTools.git -
Restart ComfyUI
Nodes
Text Manipulation
String Index Selector
Extract a single element from a delimited string by index - perfect for loop workflows.
Inputs:
text(STRING): The delimited string to splitdelimiter(STRING): Character(s) to split on (default:,)index(INT): Which item to extract (0-based by default)output_type(STRING/INT/FLOAT): Type to cast result tostrip_whitespace(BOOLEAN): Remove leading/trailing spaceszero_indexed(BOOLEAN, optional): Use 0-based indexing
Outputs:
selected_item: The extracted item (typed)item_count(INT): Total number of items
Example:
Input: "10,25,42,100", delimiter: ",", index: 2, output_type: INT
Output: 42 (as integer)
String Splitter
Split a delimited string into a typed list with optional casting.
Inputs:
text(STRING): The delimited stringdelimiter(STRING): What to split onoutput_type(STRING/INT/FLOAT): Type to cast items tostrip_whitespace(BOOLEAN): Clean up itemsremove_empty(BOOLEAN, optional): Remove empty strings
Outputs:
string_list(LIST): List of typed itemsitem_count(INT): Number of items
Features:
- Type casting to STRING, INT, or FLOAT
- Escape sequence support (
\n,\t,\r) - Empty string handling
- Grid icon displays correctly (OUTPUT_IS_LIST working)
List Index Selector
Extract an item from a list by index with type preservation.
Inputs:
list_input(*): Any list (connect from String Splitter)index(INT): Which item to extractzero_indexed(BOOLEAN): 0-based or 1-based indexing
Outputs:
selected_item: The selected item (type-preserving)list_length(INT): Total list size
String Joiner
Join list items into a delimited string.
Inputs:
list_input(*): Any listdelimiter(STRING): String to insert between items (supports escape sequences)
Outputs:
joined_string(STRING): The combined stringitem_count(INT): Number of items joined
Escape Sequences: Supports \n, \t, \r, \\
JSON Processing
JSON Pretty Printer
Format JSON strings with proper indentation for readability.
Inputs:
json_string(STRING): Raw JSON to formatindent(INT): Number of spaces for indentation (0-8)sort_keys(BOOLEAN, optional): Alphabetically sort object keys
Outputs:
formatted_json(STRING): Pretty-printed JSONis_valid(BOOLEAN): Whether JSON is validerror_message(STRING): Error details if invalid
Example:
Input: [{"detect_result":[{"class":"DOG","score":0.9}]}]
Output: (formatted with indentation and newlines)
Detection Query
Query detection results with class filtering, score thresholds, and wildcards.
Inputs:
json_string(STRING): JSON containing detection resultsclass_filter(STRING): Class name with wildcards (default:*)min_score(FLOAT, optional): Minimum confidence scoremax_results(INT, optional): Maximum results to returncategorization_field(STRING, optional): Field name to extract
Outputs:
filtered_json(STRING): Filtered results as JSONmatch_count(INT): Number of matchesdetection_list(LIST): Individual detections for iterationbbox_list(LIST): List of bboxes for visualizationcategorization_value(*): Extracted field valueis_valid(BOOLEAN): Whether JSON is validerror_message(STRING): Error details if invalid
Wildcard Examples:
CLASS1_LABEL→ Exact matchCLASS1_*→ All CLASS1 subclasses*_LABEL→ All ending with _LABEL*→ All detections
Use Case: Filter detections, extract bboxes for visualization
BBox and Mask Operations
Detection to BBox
Extract bounding box from a detection object.
Inputs:
detection(STRING): JSON string of detection objectbbox_key(box/bbox): Which key contains the bbox
Outputs:
bbox(BBOX): Bounding box in format[[x, y, width, height]]x,y,width,height(INT): Individual componentsclass_name(STRING): Detection classscore(FLOAT): Confidence score
Format: Works with detection objects containing "box": [x, y, w, h] or "bbox": [x, y, w, h]
JSON to BBox
Convert JSON bbox arrays to BBOX format with coordinate system conversion.
Inputs:
json_string(STRING): JSON array of bboxes (e.g., from SAM3 Segmentation)input_format(XYXY/XYWH): Format of bboxes in JSONoutput_format(XYXY/XYWH): Format to output
Outputs:
bboxes(LIST of BBOX): Converted bboxes in format[[[x,y,w,h]], ...]bbox_count(INT): Number of bboxes
Coordinate Formats:
- XYXY: Two corners
[x1, y1, x2, y2]- used by SAM3 and other models - XYWH: Corner + dimensions
[x, y, width, height]- standard format
Example Input (SAM3 format):
[[245.3, 167.8, 512.6, 389.2], [100.0, 200.0, 300.0, 400.0]]
Use Case: Convert bbox output from nodes like TBG SAM3 Segmentation to work with mask generation nodes
BBox to Mask
Convert a single bounding box to a binary mask. Simple 1:1 conversion.
Inputs:
bbox(BBOX): Single bbox[[x, y, w, h]]width(INT): Image widthheight(INT): Image heightinvert(BOOLEAN, optional): Invert mask (bbox black, rest white)
Outputs:
mask(MASK): Binary mask for the bbox
Features:
- Simple single bbox → single mask conversion
- When connected to OUTPUT_IS_LIST sources, ComfyUI automatically iterates
- Handles both wrapped
[[x,y,w,h]]and unwrapped[x,y,w,h]formats - Automatic coordinate clamping to image bounds
Use Case: Single bbox to mask conversion. For multiple bboxes with union/combined mask, use BBoxes to Mask instead.
BBoxes to Mask ⭐ RECOMMENDED
Convert a list of bounding boxes to binary masks with union functionality.
Inputs:
bboxes(*): List of bboxes from Detection Query or JSON to BBoxwidth(INT): Image widthheight(INT): Image heightinvert(BOOLEAN, optional): Invert mask (bbox black, rest white)
Outputs:
combined_mask(MASK): Union of all bboxes in one maskindividual_masks(LIST of MASK): One mask per bboxbbox_count(INT): Number of bboxes processed
Features:
- Properly creates union mask (combined_mask) from multiple bboxes
- Individual masks for per-bbox processing
- Automatic coordinate clamping to image bounds
- Handles both wrapped and unwrapped bbox formats
Format: Accepts [[[x,y,w,h]], [[x,y,w,h]], ...] from Detection Query's bbox_list output or JSON to BBox
Mask to BBox ⭐ NEW
Convert a binary mask to a bounding box.
Inputs:
mask(MASK): Binary mask tensor
Outputs:
bbox(BBOX): Bounding box in format[[x, y, width, height]]x,y,w,h(INT): Individual integer coordinates
Features:
- Converts mask to tight bounding box
- Uses 0.5 threshold for float masks
- Floors all coordinates to integers
- Handles batched masks (uses first mask)
- Handles irregular shapes (L-shapes, non-convex masks)
- Returns [0,0,0,0] for empty masks
Use Case: Convert mask outputs (from detector nodes that output masks instead of proper BBOX type) to bbox format. Can chain output to other bbox nodes like BBox to SAM3 Query.
Example:
Mask (256x256)
↓
Mask to BBox
↓
bbox: [[50, 60, 100, 80]]
x: 50, y: 60, w: 100, h: 80 (all INT)
↓
BBox to SAM3 Query (chainable)
SEGs to Mask
Convert SEGS (segmentation results) to binary masks with filtering and union capabilities.
Inputs:
segs(SEGS): Segmentation results from TBG SAM3 Segmentation or similar nodeslabel_filter(STRING, optional): Wildcard pattern for label filtering (default:*)min_confidence(FLOAT, optional): Minimum confidence threshold (0.0-1.0, default: 0.0)min_area_percent(FLOAT, optional): Minimum mask area as percentage of image (0.0-100.0, default: 0.0)sort_order(default/x_then_y/y_then_x/confidence_high_to_low, optional): Order segments deterministicallyunion_same_labels(BOOLEAN, optional): Combine segments with same label (default: True)invert(BOOLEAN, optional): Invert mask (mask areas black, rest white)
Outputs:
combined_mask(MASK): Union of all filtered segmentsindividual_masks(LIST of MASK): One mask per label (when union enabled) or per segmentlabels_info(LIST of STRING): Label and confidence info (e.g., "person_0: 0.95")seg_count(INT): Number of masks returned
SEGS Format:
((height, width), [SEG(...), SEG(...), ...])
Each SEG object contains:
cropped_mask: numpy array with mask datacrop_region: [x1, y1, x2, y2] placement coordinateslabel: string label (e.g., "person_0")confidence: float confidence score
Features:
- Label Filtering: Use wildcards to filter by label (
person_*,*_LABEL, etc.) - Confidence Filtering: Remove low-confidence segments
- Area Filtering: Remove tiny masks below percentage threshold (e.g., 5.0 for 5% of image)
- Union Same Labels: Combines all segments with same label into one mask (default)
- Uses max confidence score for combined segments
- Example: 3x "person_0" segments → 1 "person_0" mask
- Deterministic Sorting: Order segments by position (x_then_y or y_then_x)
- Robust Handling: Gracefully handles None cropped_masks and invalid data
Wildcard Examples:
*→ All segments (default)person_*→ All person detections*_0→ All first instances of each classdog→ Exact match only
Sort Order Options:
default→ Keep original order from SEGSx_then_y→ Left-to-right, then top-to-bottomy_then_x→ Top-to-bottom, then left-to-rightconfidence_high_to_low→ Sort by confidence score (highest first) ⭐ NEW
Use Case: Convert SAM3 segmentation results to masks for image processing workflows
SEGs to SAM3 Query ⭐ NEW
Convert SEGS segmentation format to SAM3 Selector query formats.
Inputs:
segs(SEGS): Segmentation results from TBG SAM3 Segmentation or similar nodes
Outputs:
box_query(STRING): JSON array with bounding box for SAM3 Selector[{"x1": 10, "y1": 20, "x2": 100, "y2": 150}]point_query(STRING): JSON array with weighted centroid[{"x": 55, "y": 85}]
Features:
- Generates both box and point queries for SAM3 Selector node
- Weighted centroid calculation for accurate point queries
- Handles multiple segments with union masks
- Coordinates clamped to image bounds
- Works with both ImpactPack and TBG SAM3 SEGS formats
- Handles numpy array and tensor masks
- Returns empty arrays
[]for invalid inputs
Use Case: Chain SEGS segmentation output to SAM3 Selector for iterative refinement or re-segmentation.
Example Workflow:
TBG SAM3 Segmentation
↓
segs output → ((512, 512), [SEG(...), SEG(...), ...])
↓
SEGs to SAM3 Query
↓
box_query: [{"x1": 100, "y1": 200, "x2": 300, "y2": 400}]
point_query: [{"x": 200, "y": 300}]
↓
TBG SAM3 Selector
- box_coords: box_query
- point_coords: point_query
↓
Refined segmentation
Example Workflow:
TBG SAM3 Segmentation
↓
segs output → ((512, 512), [SEG(...), SEG(...), ...])
↓
SEGs to Mask
- label_filter: "person_*"
- min_confidence: 0.7
- min_area_percent: 5.0
- union_same_labels: True
↓
combined_mask → Mask of all detected persons
individual_masks → One mask per unique person
labels_info → ["person_0: 0.95", "person_1: 0.87"]
Workflow Examples
Example 1: Frame Number Extraction (Original Use Case)
VHS Node → "10,25,42,100"
↓
String Index Selector
- delimiter: ","
- index: 2 (from loop)
- output_type: INT
↓
Output: 42 (as integer)
↓
Save Image: "frame_42.png"
Example 2: Detection Visualization
Detection JSON
↓
JSON Pretty Printer (format for readability)
↓
Detection Query
- class_filter: "DOG_*"
- min_score: 0.7
↓
bbox_list output → [[[x,y,w,h]], [[x,y,w,h]], ...]
↓
BBoxes to Mask
- width: 512
- height: 512
↓
combined_mask → Apply to original image
individual_masks → Process each detection separately
Example 2b: SAM3 Segmentation to Mask
TBG SAM3 Segmentation Node
↓
boxes output (JSON) → "[[x1,y1,x2,y2], [x1,y1,x2,y2], ...]"
↓
JSON to BBox
- input_format: XYXY
- output_format: XYWH
↓
bboxes output → [[[x,y,w,h]], [[x,y,w,h]], ...]
↓
BBoxes to Mask
- width: 1024
- height: 1024
↓
combined_mask → Apply to original image
Example 3: Typed List Processing
"10,25,42,100"
↓
String Splitter
- output_type: INT
↓
[10, 25, 42, 100] (actual integers)
↓
List Index Selector
- index: 2
↓
Output: 42 (as int, not string)
↓
Can connect directly to nodes expecting INT
Example 4: Multi-line Text Processing
Multiline Text Input
↓
String Splitter
- delimiter: \n
↓
List of lines
↓
String Joiner
- delimiter: ", "
↓
Comma-separated output
Development
Running Tests
# Individual tests
python tests/test_string_splitter.py
# All tests at once
python tests/run_all_tests.py
Requirements
- Python 3.10+
- ComfyUI
- PyTorch (for mask generation)
See requirements.txt for development dependencies.
Technical Notes
BBox Format
Standard format used throughout: [[x, y, width, height]]
- Single bbox:
[[100, 200, 50, 75]] - Multiple bboxes:
[[[x1,y1,w1,h1]], [[x2,y2,w2,h2]], ...] - Coordinates are XYWH (top-left corner + dimensions)
Alternative Coordinate Systems:
- XYXY: Two corners
[x1, y1, x2, y2]- used by some detection models (SAM3, etc.) - XYWH: Corner + dimensions
[x, y, width, height]- our standard format - Use JSON to BBox node to convert between these formats
OUTPUT_IS_LIST
Nodes using OUTPUT_IS_LIST show grid icon in ComfyUI and output items for iteration:
- String Splitter:
string_list - List Index Selector: receives lists
- Detection Query:
detection_list,bbox_list - BBoxes to Mask:
individual_masks
Type Preservation
List Index Selector preserves input types:
- String list → Returns strings
- Int list → Returns ints
- Float list → Returns floats
Compatibility
Cross-Package Support
- Works with: ImpactPack (with type converter if needed)
- Works with: KJNodes BBox Visualizer
- Works with: TBG SAM3 Segmentation (via JSON to BBox node for bboxes, SEGs to Mask for segmentations)
- Works with: Standard ComfyUI mask nodes
Verified Workflows:
- TBG SAM3 → JSON to BBox → BBoxes to Mask ✅
- TBG SAM3 → SEGs to Mask (full SEGS support) ✅
Roadmap
Current Features ✅
- [x] Text splitting and joining with type casting
- [x] List indexing with type preservation
- [x] JSON formatting and validation
- [x] Detection querying with wildcards and bbox extraction
- [x] BBox extraction from detection objects
- [x] JSON bbox array conversion with XYXY/XYWH support
- [x] Mask generation from bboxes (union and individual)
- [x] SEGS segmentation to mask conversion with filtering and union
- [x] Escape sequence support
- [x] Comprehensive test suite (95%+ coverage)
Future Enhancements
- [ ] CSV Parser node
- [ ] JSONPath query support
- [ ] Regular expression nodes
- [ ] Additional bbox formats (XYXY, center-based)
- [ ] Mask operations (union, intersection, difference)
- [ ] String templating/formatting
License
MIT License
Author
John Knox (Nakamura2828)
Contributing
Issues and pull requests welcome!
Support
If you find these nodes useful, please star the repository on GitHub!
Changelog
v1.2.0 (2026-01-18)
- NEW: Mask to BBox Node - Convert masks to bounding boxes
- Converts binary masks to BBOX format in XYWH coordinates
- Outputs both BBOX type and individual x,y,w,h as INT values
- Uses 0.5 threshold for float masks
- Handles batched masks (uses first), irregular shapes, empty masks
- All coordinates floored to integers
- 12 comprehensive test cases
- Use case: Convert mask outputs to bbox format for chaining to other nodes
- NEW: SEGs to SAM3 Query Node - Convert SEGS to SAM3 Selector queries
- Generates box_query (bounding box) and point_query (centroid) for SAM3 Selector
- Weighted centroid calculation for accurate point queries
- Handles multiple segments with union masks
- Full ImpactPack and TBG SAM3 compatibility
- 12 comprehensive test cases covering all features
- Use case: Chain SEGS segmentation to SAM3 Selector for iterative refinement
- ENHANCED: SEGs to Mask Node - Added confidence sorting
- New sort_order option: "confidence_high_to_low"
- Sorts output masks by confidence score (highest first)
- Handles numpy array confidence values (ImpactPack compatibility)
- Updated tests: 18 test cases (was 17)
v1.1.0 (2026-01-17)
- NEW: SEGs to Mask Node - Convert SEGS segmentation format to masks
- Full support for TBG SAM3 Segmentation node output
- Wildcard label filtering (fnmatch patterns)
- Confidence threshold filtering (min_confidence)
- Area percentage filtering (min_area_percent) to remove tiny masks
- Deterministic sorting options (default/x_then_y/y_then_x)
- Union same labels feature (combines segments with same label, uses max confidence)
- Invert mode support
- 4 outputs: combined_mask, individual_masks (list), labels_info (list), seg_count
- Comprehensive tests: 16 test cases covering all features
- Robust handling of None masks and invalid data
v1.0.1 (2026-01-17)
- BBox to Mask Refactored: Simplified to single bbox → single mask converter
- Removed combined_mask output (use BBoxes to Mask for union functionality)
- Renamed individual_masks output to just "mask"
- Removed OUTPUT_IS_LIST - works as standard 1:1 converter
- ComfyUI now iterates automatically when connected to list sources
- Updated tests: 14 test cases validating simplified behavior
- No longer marked EXPERIMENTAL - clean, focused implementation
v1.0.0 (2026-01-17)
- Initial release with 10 working nodes (now 11 with SEGs to Mask in v1.1.0)
- Text Manipulation (4 nodes):
- String Index Selector, String Splitter, List Index Selector, String Joiner
- Full type casting support (STRING/INT/FLOAT)
- Escape sequence support
- JSON Processing (2 nodes):
- JSON Pretty Printer with validation
- Detection Query with wildcard filtering and bbox extraction
- BBox & Mask Operations (4 nodes):
- Detection to BBox - Extract from detection objects
- JSON to BBox - Convert JSON arrays with XYXY/XYWH conversion
- BBoxes to Mask - Create union and individual masks (RECOMMENDED)
- BBox to Mask - Simple 1:1 bbox to mask converter
- Comprehensive test suite (95%+ coverage)
- Full documentation (README.md + CLAUDE.md)
- Verified integrations with SAM3, KJNodes, ImpactPack
Run ComfyUI workflows without the setup
No installs, no CUDA version roulette, no GPU sitting idle on your bill. Bring a workflow and run it in the browser.