comfyui_bmad_nodes
Utility nodes for ComfyUI
Nodes (123)
The threshold that survives shadows and uneven light
Give a flat RGB image a real alpha channel
Append one string to a dozen prompts without a dozen extra nodes
Snap a crop rectangle to latent-friendly multiples without moving its center
A Python eval in your graph — powerful, and the pack will warn you about it
From 'there's a shape here' to four crop coordinates
For when a percentage knob isn't enough to mask your color
Point at a color, get the mask range for it — statistically
Give it a clean reference and it finds what changed — a mask of the difference
The checkpoint loader whose filename is a text box, built for API automation
The simple loader, minus the dropdown, for scripts that know the filename
The fix for uneven lighting before you even think about thresholding
A whole prompt queue through one CLIP node
Chromakey for flat-color images
Clip ADE20k segmentations by label
Color Clip, but you pick the replacement colors too
A ready-made palette of named colors for the CV nodes
Build your own named color dictionary
Feed hex codes into ComfyUI's color-masking machinery
The color picker this pack expects
Regional prompting as a grid, without the spaghetti
Type prompts straight into the grid, skip the encoders
Find the shapes in your mask, the OpenCV way
Turn one contour back into a filled mask
ControlNet per-pair, not per-everything
ControlNetHadamard, when your images come one at a time
Make a node see the channel count it expects
Pad an image with a border, five ways
A JSON breadcrumb so scripts know what your render did
How far is every pixel from the edge? This node answers that
See the contours you found, on top of the image
Stretch a washed-out image before you threshold it
Concatenate color lists, the boring node that earns its place
Merge conditioning lists before they hit the sampler
The Boring Node That Glues Your Float Lists Together
Stacking Image Lists for Grids, Batches and Video
Concatenate Int Lists When You Refuse to Count Manually
Merging Latent Batches Without Re-Encoding a Thing
Joining Mask Lists When You're Compositing a Whole Scene
One List of Models Instead of Ten Loaders
Merging Prompt Lists Without Merging Your Brains
Stop the Ugly White Halo When You Composite a Cutout
Rank Shapes With a One-Line Fitness Function
Ask the Image What Color It's Missing
Auto-Tune the Threshold That Gets You the Mask You Want
Turn a Latent Batch Into One Big Grid Latent
OpenCV's GrabCut With the Background Pointed Out For You
GrabCut With Separate 'Maybe' and 'Sure' Foregrounds
Index Into a Palette List
Pull One Conditioning Out of a Stack
Pull One Float Out of a List Without a Whole New Node
Pick One Frame From an Image List
Grab One Integer From a List, Negative Indexes Welcome
Extract One Latent From a Batch Without Re-Encoding
Grab one mask out of a mask list by number — FromListGet1Mask
Index into a model list without rebuilding the graph — FromListGet1Model
Pick one string out of a list for prompt roulette — FromListGet1String
Fan a color palette out into per-color sockets — FromListGetColors
Unpack a conditioning list into per-region sockets — FromListGetConds
Fan an float list out into parameter sockets — FromListGetFloats
Fan an image batch out into individual sockets — FromListGetImages
Unpack an int list for per-branch settings — FromListGetInts
Split a latent batch into single latents — FromListGetLatents
Split a mask list back into individual sockets — FromListGetMasks
Unpack a model list into sampler branches — FromListGetModels
Split a string list into individual sockets — FromListGetStrings
Pick one OpenCV contour out of the pile — Get Contour from list
Your API script's way to know what models actually exist
Dump your workflow as API JSON from inside ComfyUI — Get Prompt
Set how hue wraps in color thresholding — Hue Mode (InRange hsv)
Load a hypernetwork by typed name, not dropdown — HypernetworkLoader (dirty)
Split a batch into a list so nodes process one at a time
OpenCV inpainting — not diffusion, and that's the point — Inpaint
Turn '1,2,3' into an INT_ARRAY — and survive API JSON while you're at it
Chroma-key a color range out of an image — InRange (hsv)
Posterize an image down to N dominant colors — KMeansColor
Turn a base64 blob into an image — no API key required — Load 64 Encoded Image
Type your LoRA name instead of picking it — when your workflow runs itself
One sampler, many grid cells — DIY regional control without the regional packs
Blur the outside of a mask, not the inside — the collage secret nobody ships
Stitch a batch of latents back into one image — the other half of the grid trick
Merge two masks by max or min — the two-line idea that saves you a node pack
Erode, dilate, open, close — the mask-cleaning kit you keep reaching for
Reduce a fat mask to a one-pixel line — for measuring, tracing, and contour work
Posterize automatically — let the elbow decide how many colors the image actually has
Stop hand-tuning thresholds — Otsu finds the line between black and white for you
Cut a subject out of a photo with one rectangle — no model, no prompt, just OpenCV
The sink node every Remap distorts into — without it, the family is just math
Add or remove real lens distortion — the a/b/c/d of barrel and pincushion
Unwrap a curved band back into a flat strip — the reverse of the parabola bend
Straighten the tilted document, screen, or sign
Bend a straight strip along two curves — the 'wrap text around a shape' trick
Curve-fit fixes for when the simple parabola warp comes out twisted
Squeeze a photo toward its center — the lens effect with three knobs
The proper way to undo a lens bend — root-finding instead of a shortcut formula
Push a photo outward from its center — the bulge that pinch's inverse gives you
Wrap a flat image around the inside of a cylinder — your wide-lens room view
Wrap an image around the outside of a cylinder — label-on-a-bottle, done in two knobs
Perspective-paste one image onto any tilted surface
RemapWarpPolar for watch faces, dials and iris shots
Repeat Into Grid (image) makes contact sheets without touching a pixel
Repeat Into Grid (latent) tiles before the VAE decode
Unpack a JSON request straight into your ComfyUI graph
Get a color into the scale OpenCV's masking actually wants
Stop guessing HSV bounds, steal them from a reference image
The request-driven saver that skips the workflow metadata
Paste anything into a photo and watch the seams vanish
The same magic, minus the placement math
SetRequestStateToComplete closes out an API request
The text node at the root of every prompt branch
The float twin of String to Integer, for when your API sends decimals as text
The boring node that keeps your API workflow alive
Bundle your palette colors into a list
Bundle your conditionings into one list wire
Gather your weights, CFG values and denoise levels into a list
Gather separate images into a single list
Collect your seeds, steps and counts into a list
Collect loose latents into one list
Bundle your masks into one list
Line up several models into one list
Gather your prompts and text into a list
UnGridify (image)
One latent batch from many images (no wiring gymnastics)
ComfyUI Bmad Nodes
Miscellaneous assortment of custom nodes for ComfyUI.
The nature of the nodes is varied, and they do not provide a comprehensive solution for any particular kind of application. The nodes can be roughly categorized in the following way:
- api: to help setup api requests (barebones).
- computer vision: mainly for masking and collage purposes.
- general utility: simplify the workflow setup or implement some missing basic functionality.
<details><summary> Documentation </summary>
In order to keep the documentation brief and to the point, I will use the following icons for special nodes.
- ❔ the node has additional options when right-clicking, some of these options need to be used for the node to work.
- 📓 the node depends on an external library, and the requirements must be installed for it to work.
- 📄 the node relies on custom nodes external to this collection, they will only work if the needed nodes are installed.
- ❌the node won't work on vanilla comfyUI at the time of writing.
- ⚠️the node is potentially dangerous. Although they should be fairly safe in most cases, it is NOT advised to run them from unknown sources unless you know what they are doing. For better visibility these nodes are forcefully painted white.
Furthermore, I won't provide any documentation for api nodes, as I think there are better, more comprehensive and already documented, solutions available.
General Purpose
| Node | Description |
|------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| String | Just a string (text). In case you want it written before connecting to a node or if some custom node does not work properly with the PrimitiveNode. |
| Add String to Many ❔ | Will append/prepend the string to_add to all the other strings. |
| Color Clip | Clips the color (or all the other colors) from an image. Both the target color or the complement can be set to white, black or remain untouched. |
| Color Clip ADE20k 📓️ | Similar to Color Clip, but you pick the color from the ADE20k class list. Only useful for ADE20k semantic segmented images. |
| MonoMerge | Selects the maximum (or minimum) value between two images. Mainly used for mask composition. |
| AdjustRect | Receives a rectangle and returns a new rectangle that shares the same center but with width adjusted to a multiple of xm and height to a multiple of ym. Setting round_mode to exact will return a rectangle with the exact defined dimensions. |
| Repeat Into Grid | Tiles the provided image/latent into a grid of columnsxrows tiles. |
| Conditioning Grid (cond) ❔ | Creates conditioning areas of size widthxheight, forming a grid of columnsxrows conditioning areas. The inputs notation can be read as: r{row}_c{column}. strength is the strength to by applied in all the areas, and base is the base conditioning prior to setting the tiles conditioning. |
| Conditioning Grid (string) ❔ | Similar to Conditioning Grid (cond), but generates the conditioning from the given strings (only). |
| Conditioning Grid (string) Advanced 📄 ❔ | Similar to Conditioning Grid (string), but requires BlenderNeko's Advanced CLIP Text Encode. |
| VAEEncodeBatch ❔ | Receives multiples images and encodes them into a latent batch. |
| AnyToAny ❌ ⚠️ | Can be used to convert data between different formats or compute stuff. The input data can be used in the expression using the letter v. |
| CLIPEncodeMultiple ❔ | Receives individual strings → CLIPEncodes each → returns conditioning list. |
| CLIPEncodeMultipleAdvanced 📄 ❔ | Same as CLIPEncodeMultiple, but using BlenderNeko's Advanced CLIP Text Encode. |
| ControlNetHadamard | Receives a list of conditionings and a list of images → Applies contronet only once per conditioning/image pair (does not apply every image to every conditioning). |
| ControlNetHadamard (manual) ❔ | Similar to ControlNetHadamard but images are set via individual inputs. |
| ToCondList ❔ | Receives individual conditionings → returns a list with all the input conditionings. |
| ToLatentList ❔ | Receives individual latents → returns a list with all the input latents. |
| ToImageList ❔ | Receives individual images → returns a list with all the input images. |
| FromListGetConds ❔ | Receives a list of conditionings → returns the conditionings via individual slots. |
| FromListGetLatents ❔ | Receives a list of latents → returns the latents via individual slots. |
| FromListGetImages ❔ | Receives a list of images → returns the images via individual slots. |
CV (Computer Vision) nodes
Nodes under the CV separator use or expose openCV functionalities.
I will only provide partial documentation here, to clarify how to use the more complex nodes. The remaining nodes usage should be clear given the nodes' names.
Framed Mask Grab Cut
Returns a mask, in image format, with the result of the grabcut.
<details> <summary> usage </summary>The tresh input should be a gray image, possibly a mask in black and white but not necessarily (read thresholds).
It is used to set most of the grabcut input mask's flags, excluding GC_BGD (sure background) which are set by the "frame".
The "frame" - border margins of the image - has its size defined via the pixels input, and won't affect sides set to
be ignored by the frame_option input (the corners common to neighbor sides will still be painted on the ignored sides).
The threshold inputs indicate the intensity threshold's used to set GC_PR_FGD (probable foreground) or GC_FGD (foreground).
The values equal or above the thresholds are set with the indicated flag. They can be setup in the following manners:
- To only use probable foreground, set threshold_FGD to exactly 0, and it will be ignored.
- To only use foreground, set threshold_FGD to a lower value than threshold_PR_FGD.
- To have both, keep threshold_FGD higher than threshold_PR_FGD (make sure your thresh input image contains values in the intended range).
The thresholds also work as safeguards against potential misleading or inconsistent input images, where the image may appear to be only black and white, but actually contains values besides 0s and 255s.
Framed Mask Grab Cut 2
Similar to Framed Mask Grab Cut, but uses thresh_maybe to set the probable foreground, and thresh_sure to set the foreground.
The threshold value is the same for both thresh image inputs; the GC_FGD flags are set by the thresh_sure on top of the GC_PR_FGD flags set by thresh_maybe.
Filter Contour ⚠️
Will output contours depending on their fitness, where the fitness function must be provided within the node's text box.
The expression may be long but can't have multiple instructions, only a single line that returns the fitness when evaluated.
<details> <summary> usage </summary>Select argument options:
MAX,MIN: select the contour (singular) with higher and lower fitness respectively, the evaluated expression should result in a number.FILTER: filters the contours (plural) that satisfy the fitness condition, the evaluated expression should result in a boolean.MODE: selects the contour (singular) whose fitness score is the mode of all the contours fitness scores.
To compute the fitness, the input parameters can be used with the following names:
c: the contour being evaluated, from input contoursi: input image (optional)a: input auxiliary contour (optional)
Functions from the math, opencv and numpy modules can be used with the prefixes: m; cv; and np, respectively.
Additionally, functions listed below can also be used without a prefix.
The following is an example fitness function to get the contour that best matches the auxiliary contour (the lower the value, the better the match):
cv.matchShapes(c,a,1,0.0)
List of available functions:
- aspect_ratio(contour): bounding rectangle's width divided by height
- extent(contour): contour area divided by bounding rect area
- solidity(contour): contour area divided by hull area
- equi_diameter(contour): how round is the shape
math.sqrt(4 * area / math.pi) - center(contour)
- contour_mask(contour, image)
- mean_color(contour, image)
- mean_intensity(contour, image)
- extreme_points(contour)
- intercepts_mask(contour, image)
does not cache result
All the listed functions cache the results at least once (details vary); they don't create computational overhead for being called more than once. This behavior was also added to the following list of opencv functions, which must be called without the cv prefix:
- boundingRect
- contourArea
- arcLength (called without the boolean arg; is always sent with
true) - minEnclosingRect
- minEnclosingCircle
- fitEllipse
- convexHull