BBox From Mask (MEC) (legacy)
The tight box around a mask — and the legacy tag explained
- mask
- bbox
- x
- y
- width
- height
- bbox_str
The job is as simple as it sounds: hand it a mask, get back the smallest rectangle that contains every pixel above your threshold. That rectangle is the thing you need for cropping to a region before an inpaint pass, for feeding a box prompt into SAM, or for reporting where in the frame something actually is.
You should know up front that this node is marked legacy. In April 2026 the pack's author pulled BBoxFromMask, BBoxToMask, BBoxPad, BBoxCreate and BBoxCrop out of the live BBox category because they duplicated what Impact Pack and core ComfyUI already ship. They were re-registered later as deprecated compatibility classes - the workflow saved in 2025 that references BBoxFromMask still loads and still runs, but the node is hidden from the node search menu and it will not get fixes.
How it works
The mechanism is about four lines of tensor code: threshold the mask (>= threshold, so partially-soft edges count as outside), torch.nonzero to get the coordinates of every surviving pixel, then min/max on the two axes. Padding is added symmetrically afterwards - padding applies to both axes, padding_x adds extra on both the left and right, padding_y does the same vertically - and the result is clamped so the box can never run past the image edge or produce a negative dimension.
Outputs are bbox (the four numbers as [x, y, width, height]), the loose x, y, width and height integers, and bbox_str, a JSON string of the same box. That last one is the useful escape hatch: feed it to a text node, to a filename, or into any node that takes a JSON box.
The two traps
It only looks at the first mask in a batch. If a video batch comes in, the node takes mask[0] and ignores frames 1..n. For anything temporal you want a per-frame box - which means running it per frame, or using a tracker.
An empty mask returns the entire frame. Nothing above the threshold means no coordinates, and the code returns [0, 0, W, H] - a full-frame box, with no warning. Downstream that looks like a legitimate answer, so a mask that failed to generate gives you a crop of the whole image rather than an error. If a crop looks suspiciously un-cropped, check the mask before you check the box node.
The threshold default of 0.5 bites on feathered masks too. A soft edge means "the box is where the mask got half-serious", which is tighter than the visual edge. Drop it to 0.1–0.2 if you're boxing a feathered matte and want the full extent.
Install
The node ships inside the pack, so a pack install is the node install:
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
Or install "CustomNodePacks" from ComfyUI Manager. The pack needs opencv-python, scipy and safetensors, but this particular node is plain PyTorch - if the pack loads at all, this works. Do not blindly run pip install -r requirements.txt: ComfyUI ships its own torch, torchvision, numpy and Pillow, and the pack's README explicitly warns about overwriting them. Check what you have first:
pip list | grep -i "opencv\|scipy\|safetensors"
Should you be using it in a new graph?
Probably not, and that's not a knock on the maths - it's that the ecosystem standardised on other boxes. Core ComfyUI has PrimitiveBoundingBox for making rectangles by hand, and Impact Pack owns the detection side of this world with its BBOX/SEGS types, which is where an automatic box usually comes from in a detailer pipeline. This node's real value now is as a small, dependency-free converter between the mask world and the box world, and as a reason the graph you downloaded in 2025 still opens.
The one thing it does better than a lot of the alternatives: the box normaliser accepts several shapes, including kijai/SAM2-style nested [[[x1, y1, x2, y2]]] XYXY batches, so a box coming out of a segmentation node doesn't need a converter node between it and this one.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| padding | INT | 00–512 | Uniform padding around the detected bbox |
| padding_x | INT | 00–512 | Extra horizontal padding (added to both sides) |
| padding_y | INT | 00–512 | Extra vertical padding (added to both sides) |
| threshold | FLOAT | 0.500–1 | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| bbox | BBOX | — |
| x | INT | — |
| y | INT | — |
| width | INT | — |
| height | INT | — |
| bbox_str | STRING | — |