Smart Image Crop (Still)
Stop resampling the whole frame to fix one region
- image
- mask
- crop_image
- crop_mask
- stitcher_info
- preview_overlay
The fastest way to wreck a high-res image is to run the whole frame through your model just to fix one eye. Smart Image Crop is the fix for that habit: you hand it an image and a mask, it finds the masked region, crops it, and hands you a clean, model-friendly patch to process - plus a little bag of coordinates so its sister node can put the result back exactly where it came from.
This is a re-imagining of lquesada/ComfyUI-Inpaint-CropAndStitch, the node pair that quietly became the default way to do masked edits in ComfyUI. The reason it won is structural: when you crop first and stitch after, the unmasked pixels never pass through a VAE encode/decode cycle, so they come back bit-identical. No drift, no accumulated degradation across a chain of edits. The same pattern is how people run Qwen-Image-Edit or Flux 2 Klein inside a mask in 2026 - process only the region, paste it back, leave the rest of the frame alone. This pack is that pattern with the fiddly parts automated.
How it works
The node takes your image and mask, then does a small pipeline of fixes before it ever crops:
- It detects even very light grey mask pixels and binarizes them into a solid mask. Masks you painted at 50% opacity don't silently vanish.
- Optionally fills holes (
patch_mask_holes), then grows or shrinks the mask bymask_grow_pixels- positive grows, negative shrinks. If you draw tight around a face, a grow of 32–64px gives the model breathing room to blend. - It computes the bounding box and crops from the source with edge-padding, so crops that hang off the canvas still come back with content (replicated edges) instead of black bars.
- It resizes the crop to a target size, snapping dimensions to the
force_divisibilityvalue - 128 by default, which the tooltip correctly calls "crucial for VAEs." It also squares up the capture aspect ratio to match the target, so the AI never gets a squashed image.
The inputs that matter
You can ignore most of these on day one. The ones to actually touch:
resolution_mode-AutomaticorManual. Automatic picks a size betweenmin_resolution(768) andmax_resolution(2048) that fits your model; Manual usesmanual_width/manual_heightand snaps them up to your divisibility.mask_grow_pixels- the single most useful dial. Positive grows the crop region, negative shrinks it.patch_mask_holes- on by default; fills enclosed holes so the mask is one solid shape.no_mask_mode- what happens when no mask pixels are found:Bypass(pass the image through untouched),Resize Full Image, orCrop Full Image. That's what lets one workflow handle both masked edits and full-image upscale jobs.
The four outputs: crop_image and crop_mask go into your inpaint/detail/upscale chain. stitcher_info is the DICT that records where the crop came from - feed it to Smart Image Stitcher. preview_overlay shows you a red mask tint and a green crop border so you can see exactly what will be processed before you commit.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/HallettVisual/ComfyUI-Smart-Image-Crop-and-Stitch.git
Restart ComfyUI and the nodes appear under Smart Image Tools. It's also set up for ComfyUI Manager (registry id smart-image-crop-and-stitch) once it lands in the registry. The only Python dependency is opencv-python - used for the morphological mask fixes - and there are zero model downloads. This is a pure utility pack; it doesn't touch the sampler at all.
Common issues
- VAE errors on odd sizes - that's
force_divisibility. If your pipeline complains about dimensions, drop it to a value your model actually wants (16, 32, 64) or keep 128 and don't fight it. - Multiple crops, batch order - a batch in means a batch out, and the stitcher matches processed patches to positions by index. Keep the crop output's batch order intact through your processing nodes.
- Stale node state - the README warns that existing workflows may need nodes refreshed or re-added after input changes. The crop's no-mask behavior was changed at some point (an empty mask now passes through cleanly instead of falling back to a center crop), so old saved graphs can surprise you.
It's not flashy and it won't be on any "essential nodes" listicle yet, but if you inpaint, detail, or upscale small regions on big images, this is the node that stops you from paying for the whole frame to fix one eye.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | — | |
| resolution_mode | COMBO | Automatic | 2 options: Automatic, Manual |
| max_resolution | INT | 2048256–16384 | MAX LIMIT: If the cropped area is larger than this, it will be SCALED DOWN so its longest side equals this value. |
| min_resolution | INT | 76864–2048 | MIN LIMIT: If the cropped area is smaller than this, it will be SCALED UP so its longest side equals this value. |
| manual_width | INT | 102464–8192 | — |
| manual_height | INT | 102464–8192 | — |
| mask_grow_pixels | INT | 32-1024–1024 | Grow or shrink the detected mask before cropping. Positive grows, negative shrinks. |
| patch_mask_holes | BOOLEAN | true | Fills small holes and gaps in the detected mask to ensure a solid shape. |
| no_mask_mode | COMBO | Bypass | What to do when no mask pixels are detected. |
| force_divisibility | COMBO | 128 | Ensure output dimensions are divisible by this number (crucial for VAEs) |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| crop_image | IMAGE | — |
| crop_mask | MASK | — |
| stitcher_info | DICT | — |
| preview_overlay | IMAGE | — |