ComfyUI Node

Smart Image Crop

That 200px face deserves 1024px of the model's attention

By Code2Collapse·Created 7 months ago·Updated 2 days ago· 56
Smart Image Crop
  • image
  • mask
  • crop_image
  • crop_mask
  • stitcher
  • preview_overlay
  • info
resolution_modeAutomatic
max_resolution2048
min_resolution768
manual_width1024
manual_height1024
mask_grow_pixels32
patch_mask_holestrue
no_mask_modeBypass
force_divisibility128

Why crop at all

The argument in the KB's inpainting doc is the one that matters: whole-frame editing can't spend generation budget locally. A face occupying 200 pixels of a 2048px render has 200 pixels' worth of latent to work with, no matter how good the checkpoint is. Crop it out, render the crop at 1024, paste it back, and that face gets the model's full attention. That's the loop every automatic detailer runs - detect, crop, re-render, paste back - and Smart Image Crop is the middle two steps for stills.

It's a port of ComfyUI-Smart-Image-Crop-and-Stitch, itself a rework of lquesada's Inpaint-CropAndStitch, and it does four things the older lineage doesn't, all four of which come from real complaints: a very light grey mask still counts as a mask, holes get filled, the crop is taken at the target aspect rather than cropped-then-squashed, and dimensions snap to a VAE-friendly multiple. If you already use Inpaint Crop Pro (MEC) from this same pack, that's the video-aware sibling with a canvas; this is the stills path.

What it does, step by step

It takes the tight bounding box of everything above 1/255 in the mask (a faint mask is still a mask - testing for exactly 1.0 throws away real selections and crops the whole frame, which looks like the node ignoring you), grows the mask by mask_grow_pixels before measuring, fills enclosed holes if patch_mask_holes is on, widens the box to the output aspect, snaps the output size to force_divisibility, and resamples. Up-scaling uses bicubic, down-scaling uses area, which is the correct pair and not something every crop node bothers with.

The crop window is centred on the region and may run past the frame edge - where it does, the edge pixel is repeated, and the stitcher records the pad offset so the stitch can undo it. A crop entirely outside the frame comes back blank instead of erroring.

Inputs

  • image, mask - required. Faint masks count; a genuinely empty one triggers no_mask_mode.
  • resolution_mode - Automatic (size derived from the crop, clamped) or Manual (use manual_width/manual_height exactly).
  • min_resolution (default 768) and max_resolution (default 2048) - the whole point. A crop whose short side is below min_resolution is scaled up; a long side above max_resolution is scaled down. Set them the other way round and the node refuses with a clear error rather than silently picking one.
  • manual_width / manual_height - Manual mode only.
  • mask_grow_pixels - default 32, and it can be negative to shrink. This is your "how much context around the subject does the model get" control. Zero gives a tight cut-out, which is how you get the model painting a fresh background around your subject's chin.
  • patch_mask_holes - leave this on. A subject mask with holes regenerates those holes as background: the hole-in-the-face result. The info string tells you which backend did the filling; without OpenCV installed it degrades to a torch flood fill that gives up on holes wider than ~128px, and it says so.
  • no_mask_mode - Bypass (default), Resize Full Image, Crop Full Image. Bypass is the right default for a batch where only some frames have a mask.
  • force_divisibility - 8/16/32/64/112/128/256, default 128. A VAE silently pads anything that isn't a multiple of 8 (and 112 for some architectures), which shifts your crop a few pixels and shows up later as a misaligned stitch. Snap it here, deliberately, rather than discovering it at the seam. 112 is in the list for a reason - that's the Qwen-Image / edit-model multiple the KB's inpainting doc calls out.

Outputs

crop_image and crop_mask (the crop and its mask, same size, ready for any sampler), stitcher (a STITCHER typed payload - not a raw dict, deliberately, so it can't be wired into the wrong socket and fail somewhere far away), preview_overlay (red tint over the mask, green box for the crop rect - the fastest way to see whether the crop is where you think it is), and info.

One batch behaviour worth knowing: the batch gets one target size, taken from the largest region in it, because a single tensor can't hold differently-sized crops. Frames with no mask get a centred full-frame window rather than being dropped, so the batch length survives.

Install

ComfyUI Manager → search "CustomNodePacks", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks

Restart ComfyUI. Install opencv-python if you can - hole filling uses it, and the torch fallback is honest about its limits. No models, no VRAM. And the README's standing warning: check pip list rather than running pip install -r requirements.txt blind, since it lists packages ComfyUI already provides.

Common issues

  • "It cropped the whole frame." The mask was empty (or effectively empty) and no_mask_mode did its job. Check the info string.
  • The stitched result is offset by a few pixels. Divisibility mismatch or a resized full image. Check force_divisibility and make sure Smart Image Stitch is getting resize_full_image_output right.
  • A hole survived in the output. The image was regenerated with the hole as background because hole filling was off, or the hole was wider than the torch fallback's limit. Turn patch_mask_holes on and install OpenCV.
CategoryC2C/Inpaint

Inputs (11)

NameTypeDefaultDescription
imageIMAGE
maskMASK
resolution_modeCOMBOAutomatic2 options: Automatic, Manual
max_resolutionINT2048256–16384Upper limit on the longest side. A crop larger than this is scaled DOWN to fit.
min_resolutionINT76864–2048Lower limit on the shortest side. A crop smaller than this is scaled UP, which is the whole point of cropping - a 200px face gets the model's full attention.
manual_widthINT102464–8192
manual_heightINT102464–8192
mask_grow_pixelsINT32-1024–1024Grow (or shrink) the mask before measuring the crop, so the model sees context around the region rather than a tight cut-out.
patch_mask_holesBOOLEANtrueClose gaps and fill enclosed holes. A subject mask with holes regenerates those holes as background - the hole-in-the-face result.
no_mask_modeCOMBOBypassWhat to do when the mask is empty. Bypass passes the image through untouched, which is the safe default for a batch where only some frames have a mask.
force_divisibilityCOMBO128Snap output dimensions to this multiple. A VAE silently pads anything else, which shifts the crop by a few pixels and breaks the stitch.

Outputs (5)

NameTypeDescription
crop_imageIMAGE
crop_maskMASK
stitcherSTITCHER
preview_overlayIMAGE
infoSTRING