CMK Image and Mask Switch
One Boolean, Two Pairs, No Magic
- image_false
- image_true
- mask_false
- mask_true
- image_output
- mask_output
- boolean
An if/else for images that have a mask attached. If boolean_value is true you get the _true pair; if it's false you get the _false pair. No lazy evaluation, no branch pruning, no hidden behaviour - which is both its virtue and the thing that will surprise you.
How it works
Five required inputs: image_false, image_true, mask_false, mask_true, and boolean_value (default false). Three outputs: image_output, mask_output, and boolean.
The selection is a two-line conditional in the source, and the boolean is passed straight through as an output. That third output is the small useful touch: whatever logic produced the switch also needs to know which way it went elsewhere in the graph, and you can fan it out from here instead of recomputing it.
The thing you need to know
All four inputs are required, and both branches get evaluated. This is not a lazy gate. ComfyUI will resolve the upstream nodes feeding image_true and image_false (and both masks) whether or not they're selected, because nothing here is marked lazy and there's no check_lazy_status to prune the unused side.
If both branches are cheap, this is fine and it's the simplest thing that works. If one of them is an expensive detector plus a SAM pass, you'll pay for both every run - which is exactly why CMK's developer category contains lazy alternatives that block the inactive side with an ExecutionBlocker instead of computing it and discarding the result.
So the honest framing: this is the toolbox version of a switch. It's in CMK/Toolbox/Mask & SEGS, the part of the pack you're meant to wire freely, not the guided pipeline's machinery.
When you'd reach for it
Mask-pair switching. Plenty of CMK nodes consume an image and a mask together - detailers, paste-back, mask detailers. When you want to decide at runtime which pair they get, a switch that keeps the two in sync is exactly right. Switching image and mask separately is a fast route to a mask that describes the wrong picture.
A/B on a manual toggle. Wire a boolean primitive (or a reroute from one) and you get a compare toggle without rewiring the graph.
Gating a masked path on whether a mask exists. Pair it with something that can tell you a mask is non-empty. The pack's load-and-resize node computes exactly that internally for its process pipe, but you can build the same thing yourself: an empty-mask branch that goes to the unmasked image, a real-mask branch that goes to the masked one.
Install
Manager: search CMK Flow, install the CMKFlow entry, restart. Manually, from your ComfyUI root:
git clone https://github.com/CMKFlow/cmk_nodes.git custom_nodes/cmk_nodes
python3 custom_nodes/cmk_nodes/scripts/install_cmk_requirements.py
That second command isn't optional after a git clone - the pack's dependencies (ultralytics, onnxruntime, insightface, segment-anything, imageio-ffmpeg, nudenet, opencv-python) are installed by that helper and never by git, and it finishes with CMK dependency check: OK when the environment is right.
This node itself is pure Python - no models, no inference. If it loads but its neighbours don't, you're looking at a dependency or a weight file rather than the pack:
python3 custom_nodes/cmk_nodes/scripts/check_cmk_resources.py --models-root "/path/to/ComfyUI-Shared"
ComfyUI's Nodes 2.0 / Vue setting should be on, as with the rest of the pack - CMK tells you at startup if it isn't.
Gotchas
Type discipline matters here more than usual. The mask slots are MASK, not IMAGE. A grayscale image that "looks like a mask" won't connect, and that's the engine doing you a favour.
The boolean output confused people. It's a pass-through of the input, not an indicator that something switched - it's the same value you sent in. It's there so you can drive two switches from one control without wiring the boolean twice.
Both branches run. Said again, because it's the one property of this node that costs real time when you forget it.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image_false | IMAGE | — | |
| image_true | IMAGE | — | |
| mask_false | MASK | — | |
| mask_true | MASK | — | |
| boolean_value | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image_output | IMAGE | — |
| mask_output | MASK | — |
| boolean | BOOLEAN | — |