Crop Image by Mask MXD
Crop to your subject's bounding box in one node
- image
- mask
- image
You've detected a face, or a subject, or a region - you've got a mask that marks it - and now you want the image cropped to exactly that region so you can do a focused pass on it. That's the classic detect-crop-refine loop that Impact Pack made famous, and Crop Image by Mask MXD is the "crop" half of it in a single small node: give it an image and a mask, get back the image cropped to the mask's bounding box.
What it is
A straightforward utility: image + optional mask in, cropped image out. It finds the tight bounding box of the non-zero mask region (with a +1 pixel nudge so the upper bounds are exclusive, like PIL expects), slices the image to that box, and returns it. The crop is a plain tensor slice - no resampling, no padding, no surprise rescaling. What you asked for is exactly what you get.
How it works
Three behaviors matter:
- No mask / empty mask → original image out. If you don't connect a mask or the mask is all zeros, it passes your image through unchanged. Nice safety default - the node never errors on an empty detection.
- Batch-aware. It handles a batch of images, cropping each against its corresponding mask. But here's the honest limitation: if any single mask in the batch is empty, it bails and returns the whole original batch with a console warning. That's because stacking crops of different sizes would crash
torch.cat- and the author chose a safe fallback over a cryptic error. - All crops must match size. Similarly, if two masks in a batch produce different-size crops, the stack fails. For batch work, make sure your masks are consistent in footprint.
Inputs and outputs
- image - the batch to crop.
- mask - optional. The non-zero region defines the crop box.
- Output: image, the cropped result.
That's the entire surface - it's deliberately thin.
Where it fits
The classic pairing is detection → mask → crop → detail pass → paste back (Impact Pack's paste/combine nodes handle the "put it back" half). It's also handy for prepping a detected face region for a LoRA-focused regeneration, or cropping away dead space before an upscale so you don't waste VRAM on background. If you're doing this by hand with a CropByCoords and a bbox node, this collapses the pair into one.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Maxed-Out-99/ComfyUI-MaxedOut.git
Restart, or ComfyUI Manager → search "Maxed Out" → install. No extra dependencies - pure tensor slicing.
Troubleshooting
- "Warning: An empty mask was found in a batch. Returning original images." - that's the safe-fallback in action. Either a frame genuinely had no detection, or your mask is misaligned with the batch (e.g. one mask for a 10-frame batch). Check the mask.
- Cropped result looks identical to input - no mask connected or mask all zeros. Connect one.
- Crop is smaller than you expected - the crop is tight to the mask. If you want margin around the subject, dilate the mask upstream (Impact Pack has dilation built into its detector nodes).
For the crop step of a detail loop, it's exactly the node you'd want - no configuration, no surprises, just a correct crop.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| maskopt | MASK | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |