Crop By Mask
Crop exactly to your subject, and get the offsets to paste it back
- image
- mask
- image
- mask
- X
- Y
- Width
- Height
Almost every serious ComfyUI workflow - inpainting a face, upscaling a region, refining a detail - wants the same thing: crop tight around the part that matters, work on it, and paste it back exactly where it was. That "paste back exactly" is where most crop nodes fall apart, because they hand you pixels and make you guess the offsets. UC_CropByMask is the version that hands you everything: the cropped image, the cropped mask, and the X, Y, Width, Height you need to reverse the operation.
The mechanism is simple and deterministic: it finds the combined nonzero bounds of your mask, adds padding pixels around them, and then expands the crop dimensions outward to the next multiple of multiple - without resizing either the image or the mask. Defaults are padding 64 and multiple 8, and both are stepped inputs (padding in 8s, multiple in 4s) so you can't type nonsense. The multiple alignment is the quietly important part: it makes the crop dimensions friendly to the latent-space and tiling math that downstream nodes expect, since a 62×118 crop is a far more annoying thing to feed an inpainting or upscale chain than a 64×120 one.
Outputs are the full contract, in order: image and mask (both cropped to the same bounds), then X, Y, Width, Height as integers. The X/Y outputs are what make this a "crop and remember" node - feed them, plus the original image, into a paste/merge node (the pack's UC_ImageCropMerge is a natural partner) and the region goes home. It also handles two silent corrections: if the mask resolution doesn't match the image, the mask is resized to fit using nearest-exact (hard binary edges), and a single mask is broadcast across an image batch so a batch of images with one shared mask works without you noticing.
Where people get bitten: the mask bounds are the combined bounds, so if your mask has stray specks far from the subject, the crop balloons to include them. Clean the mask first (threshold it, or use the pack's mask-modify nodes) and the crop snaps tight. Second, multiple only rounds up and padding only adds - so you'll never get a crop smaller than the mask plus padding, which is by design but surprises people who expected a razor-tight cut. And remember the numbers you got are absolute pixel offsets in the original image; if you resize the crop downstream, the offsets no longer apply - either work at crop resolution and resize the result back, or rescale the offsets by the same factor.
This is plumbing in the best sense: it doesn't touch pixels creatively, it just makes the geometry honest. Install is pack-standard - Manager search "ComfyUI-UtilsCollection" or git clone into custom_nodes - with no models and no extra downloads. It's one of the first nodes I'd reach for when building a detail-refinement loop, precisely because it's boring and correct.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| padding | INT | 640–16384 | Pixels added around the combined nonzero mask bounds before alignment to the selected multiple. |
| multiple | INT | 84–256 | Expand the crop dimensions to this pixel multiple without resizing the image or mask. |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| X | INT | — |
| Y | INT | — |
| Width | INT | — |
| Height | INT | — |