Crop By Mask (UTK)
Crop tight to the mask, not to whatever box you guessed
- image
- mask_for_crop
- croped_image
- croped_mask
- crop_box
- box_preview
- remaining_area
The detect-crop-refine pattern needs one thing done right: a crop box that actually hugs the subject. Crop By Mask (UTK) computes that box from a mask instead of relying on you guessing coordinates, crops the image and the mask together, and - usefully - gives you the crop box and a preview so you can see what it decided. It's the crop engine behind the pack's inpaint/restore workflow, and it's a faithful, if simpler, take on the mask-crop utilities that Impact Pack made famous.
How it works
Feed it an image and a mask_for_crop. The detect mode picks how the crop box is found:
min_bounding_rect(the default behavior) - the tightest rectangle that contains the masked region. What you want 95% of the time.max_inscribed_rect- the largest rectangle that fits inside the mask. For ring- or donut-shaped masks where a bounding box would include the hole.mask_area- effectively the same bounding-rect math in this implementation; a compat option.
invert_mask flips which region counts, top_reserve / bottom_reserve / left_reserve / right_reserve (each default 20) add margin on each side so the subject isn't jammed against the crop edge - bump these up when faces get chopped.
Outputs
Five, and the last two are what make this usable in a loop:
- croped_image and croped_mask - the aligned crop pair, ready for a focused inpainting or upscale pass.
- crop_box - the coordinates, for pasting the result back into the original frame.
- box_preview - the image with the crop rectangle drawn on it, so you can eyeball the box before committing.
- remaining_area - the mask of what's outside the crop, useful for restoring the background later.
The pack even pairs this with a restore-crop-box node, which is the classic round-trip: crop → fix → paste back.
Installing it
Standard pack install - ComfyUI Manager → search ComfyUI-UniversalToolkit, or:
cd ComfyUI/custom_nodes
git clone https://github.com/whmc76/ComfyUI-UniversalToolkit
cd ComfyUI-UniversalToolkit && pip install -r requirements.txt
Then restart. PIL/OpenCV/numpy - all in the pack's requirements.
Gotchas
- The reserve values are pixels, not percents - 20 means 20 pixels on each side. On a 512px crop that's meaningful; on a 2048px one it's barely a hair. Scale them to your image size.
- An empty mask falls back to the full image (the bounding-rect code returns the whole frame when nothing matches). Forgiving, but it means a failed detection silently produces a full-frame crop - check box_preview, don't trust that a crop happened.
max_inscribed_rectis a simplified implementation - in this pack it effectively returns the bounding rect, not a true maximal inscribed rectangle. If you genuinely need that algorithm, Impact Pack's crop-by-mask is the more complete tool; use this for the common bounding-box case.
For the standard "mask → tight crop → refine → paste back" workflow, this is a solid, self-contained version. It won't replace Impact Pack for the hard cases, but it's enough to build the loop without installing a heavy pack - and the box_preview output alone is worth it for debugging crops.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask_for_crop | MASK | — | |
| invert_mask | BOOLEAN | false | — |
| detect | COMBO | 3 options: min_bounding_rect, max_inscribed_rect, mask_area | |
| top_reserve | INT | 20-9999–9999 | — |
| bottom_reserve | INT | 20-9999–9999 | — |
| left_reserve | INT | 20-9999–9999 | — |
| right_reserve | INT | 20-9999–9999 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| croped_image | IMAGE | — |
| croped_mask | MASK | — |
| crop_box | BOX | — |
| box_preview | IMAGE | — |
| remaining_area | MASK | — |