Mask to Bounds
Turn a mask into a crop window
- mask
- image_bounds
Mask to Bounds measures the tightest rectangle around everything a mask marks and hands it back as an IMAGE_BOUNDS value - the WAS Suite's way of saying "a region as data." Once a mask becomes bounds, it becomes a crop window for Bounded Image Crop, an inset target for Inset Image Bounds, a box to draw with Draw Image Bounds, or coordinates you can feed to an Empty Latent Image for an inpaint. It's the bridge between "I found a region with a mask" and "I want to work on just that region."
This node is part of the v3 suite's bounds family (WAS Suite/Image/Bound) - one of the genuinely new ideas in the rewrite: ten nodes that treat a region of an image as a first-class value you can measure, crop to, and paste back.
How it works
A mask goes in; the tight box around its marked area comes out. Three inputs shape the answer:
- mask - what to measure. Every mask of a batch is measured on its own, so a moving subject across video frames gives a row of boxes that follows it. Separate blobs in one mask answer as a single box covering them all - this node gives you the enclosing region, not per-blob boxes.
- threshold (default 0.5) - how bright a pixel must be to count as marked. 0.5 boxes the mask's solid core; 0.0 pulls in its whole feathered edge. If a soft-edged mask gives you a box that's larger than you expected, this is the knob - a low threshold treats faint feathering as content.
- padding (default 0) - extra pixels kept on all four sides, trimmed where the box would run past the frame. 0 is tight against the marked area; 64 leaves an inpainting pass some surroundings to match against. This is the "give the sampler context" dial from the KB's detailer loop, applied before you even crop.
The output is image_bounds - one row per mask, giving the first and last pixel row and column its marked area covers. A mask that marks nothing at the current threshold covers the whole frame instead, and the console names which one did, so a dead detector doesn't silently give you a crop of everything.
Why you'd reach for it
The highest-value wiring is region-focused inpainting: mask the thing to fix (by hand or from a detector), convert to bounds, crop that box with padding, run your inpaint pass on the crop at full resolution, and paste it back. The KB's whole detailing story is that small regions need their own generation budget - this node is how a mask becomes the rectangle that gets that budget.
It also composes with the batch side of ComfyUI: measure a batch of masks and you get a row of bounds you can iterate over, one region per frame. If your detector gives you polygons or blobs and you want individual boxes per object, this isn't the node - that's a bounding-box filter's job upstream - but for "give me the box around this mask," it's the whole answer.
Installing it
Part of WAS Node Suite v3:
cd ComfyUI/custom_nodes
git clone https://github.com/WASasquatch/was-node-suite-comfyui.git
or ComfyUI Manager → "WAS Node Suite v3", restart. ComfyUI 0.14.0+ and Python 3.10+, no pip dependencies.
Where people get burned
Two traps. Threshold first: if your mask has a big soft falloff, the default 0.5 threshold may ignore it while the visual preview clearly shows content - the box comes back tighter than you expected, or "empty" (whole frame) for a very faint mask. Lower the threshold when your mask isn't hard-edged. Padding second: people set padding expecting the box to grow, but it's trimmed at the frame edge, so a subject that touches the border can't get its full 64-pixel margin - you'll get less padding than you asked and an inpaint with less context. And remember one mask with several blobs = one box around all of them; if you need per-object crops, split the mask first.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | The mask to measure. Every mask of a batch is measured on its own, so a moving subject gives a row that follows it. Separate blobs in one mask answer a single box covering them all. | |
| threshold | FLOAT | 0.500–1 | How bright a mask pixel must be, from 0.0 to 1.0, to count as marked. 0.5 boxes a mask's solid core; 0.0 takes its whole feathered edge in. |
| padding | INT | 00–16384 | Extra pixels kept on all four sides of the marked area, trimmed where the box would run past the frame. 0 = tight against the mask; 64 leaves an inpainting pass some surroundings to match against. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image_bounds | IMAGE_BOUNDS | One row per mask, giving the first and last pixel row and column its marked area covers. A mask that marks nothing at this threshold covers the whole frame instead, and the console names which one did. |