Inpaint Crop Pro
Inpaint Crop Pro
- image
- mask
- optional_context_mask
- stitcher
- cropped_image
- inpaint_mask
- stitch_blend_mask
- info
Inpaint Crop Pro is the first half of the crop-and-stitch inpainting pattern that changed how the community edits images. The pattern comes from lquesada's ComfyUI-Inpaint-CropAndStitch: instead of running a diffusion model over the whole frame (which passes everything through VAE encode/decode and degrades pixels you didn't want touched), you crop tight around the mask, sample the crop at high resolution, and stitch it back. The unmasked part of the image never goes through the model at all - that's the property that made the pattern win. A 64px eye gets 1024px of generation budget.
This node is the lquesada API reimplemented and extended, inside ComfyUI-CustomNodePacks (the ~72-node pack from Code2Collapse / Likhith-24). It's the flagship of the author's C2C/Inpaint suite, and it produces the data structure (stitcher) that the pack's Paste Back and Stitch Pro nodes consume.
How it works
Feed it an image and a mask (white = the region to inpaint) and it:
- Computes the mask's bounding box, then grows it by
context_from_mask_extend_factor(default 1.2) so the crop includes context, not just the mask. - Resizes the crop to your target sampling resolution (
output_target_width/output_target_height, default 512×512, padded to a multiple ofoutput_padding, default 32). - Produces two separate masks: an
inpaint_maskfor the model (clean, in the crop's space) and astitch_blend_maskfor compositing back (feathered bymask_blend_pixels, default 32). - Hands you everything in one
stitcherdict plus thecropped_image,inpaint_mask,stitch_blend_mask, and aninfostring.
The knobs a beginner actually sets:
mask_blend_pixels(default 32, lquesada's number) - the feather width for the stitch seam. Too small → visible edge; too large → the inpainted region bleeds into untouched pixels.context_from_mask_extend_factor- how much context around the mask. 1.2-1.5 is a sane band.output_target_width/output_target_height- the resolution the sampler will work at. Bigger = more detail budget, more VRAM.extend_for_outpainting- with the fourextend_*_factorinputs, edge-replicates the image so you can outpaint beyond the frame. The outpainting workflow lives here.roto_quality- the pack's "Roto-Sync" mode: tightens the seam for clean alpha edges, forcing a Laplacian pyramid blend. Great for masks that need crisp boundaries.
Outputs to remember: stitcher is the thing you must preserve and feed to the stitch node - losing it means rebuilding the crop. The info string is a diagnostic worth a glance before you spend a sampler run: it tells you what the crop stage actually decided (crop box, target size, padding).
The full loop
image + mask → Inpaint Crop Pro → cropped_image + inpaint_mask → [any inpaint sampler]
└────── stitcher ──────────────────────────────→ Inpaint Paste Back / Stitch Pro → final
Use any model on the crop - Flux, Qwen-Image, a plain SD inpaint - then close the loop with the pack's stitch node.
Installing it
Ships in ComfyUI-CustomNodePacks. ComfyUI Manager → search "CustomNodePacks", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
Needs opencv-python>=4.7.0 and scipy>=1.10.0 (pack requirements - install just what's missing; the full requirements.txt can clobber ComfyUI's torch). No model downloads. Restart ComfyUI.
Common issues
- Visible seam after stitching - raise
mask_blend_pixels, or switch the stitch side to Laplacian pyramid blending, which the pack's Stitch Pro handles. - Crop too tight, model hallucinating - raise
context_from_mask_extend_factor; the model needs context to know what it's inpainting into. - Mask missing → whole image processed -
maskis optional on this node; without it the behavior degrades toward full-frame. Wire a real mask. - Model output misaligned or blurred - the KB notes even Qwen-Image-Edit-2509 misaligns slightly at native res; the crop-and-stitch pattern is precisely the community's fix for that, so keep
output_target_*a multiple of the model's favorite resolution and let Stitch handle placement.
The honest take: this is the node the whole inpaint suite is built around, and it earns its keep - crop-and-stitch is the difference between "edit the whole image and hope" and "edit exactly the pixels you meant, at full detail."
Inputs (41)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| downscale_algorithm | COMBO | bilinear | 7 options: nearest, bilinear, bicubic, lanczos, box, hamming, +1 |
| upscale_algorithm | COMBO | bicubic | 7 options: nearest, bilinear, bicubic, lanczos, box, hamming, +1 |
| preresize | BOOLEAN | false | Resize input image before processing (lquesada-style). |
| preresize_mode | COMBO | ensure minimum resolution | 3 options: ensure minimum resolution, ensure maximum resolution, ensure minimum and maximum resolution |
| preresize_min_width | INT | 10240–16384 | — |
| preresize_min_height | INT | 10240–16384 | — |
| preresize_max_width | INT | 163840–16384 | — |
| preresize_max_height | INT | 163840–16384 | — |
| mask_fill_holes | BOOLEAN | true | Mark fully-enclosed regions as masked. |
| mask_expand_pixels | INT | 00–16384 | Dilate mask by this many pixels. |
| mask_invert | BOOLEAN | false | Invert mask (anything masked is kept). |
| mask_blend_pixels | INT | 320–64 | Pixels of feather for stitch blending (lquesada default 32). |
| mask_hipass_filter | FLOAT | 0.100–1 | Zero out mask values below this threshold. |
| extend_for_outpainting | BOOLEAN | false | Extend image with edge-replicated padding for outpainting. |
| extend_up_factor | FLOAT | 1.000.01–100 | — |
| extend_down_factor | FLOAT | 1.000.01–100 | — |
| extend_left_factor | FLOAT | 1.000.01–100 | — |
| extend_right_factor | FLOAT | 1.000.01–100 | — |
| context_from_mask_extend_factor | FLOAT | 1.200.1–100 | Resize context bbox around the mask. 1.0 = exact mask bbox. >1 grows outward (1.5 = +50% on every side). <1 shrinks INWARD so the crop is tighter than the mask bbox (0.7 = inset 15% on every side). Useful for 16:9 / portrait single-still crops where the mask bbox is larger than the subject you actually want sampled. |
| auto_context_factor | BOOLEAN | false | Override context_from_mask_extend_factor automatically so the mask fills ~70% of the resulting crop area. Uses actual mask AREA (not just bbox) to handle sparse / thin / non-convex masks. Result clamped to [0.30, 10.00]. OFF = use the manual slider above. Recommended ON for batch / unattended runs. |
| aspect_preset | COMBO | Custom | Force the output crop aspect ratio. Custom : use output_target_width / _height as-is (legacy lquesada behaviour - DEFAULT). Auto : pick best of {Square, 16:9, 9:16, 4:3, 3:4} from the mask bbox aspect. Square / 16:9 / 9:16 / 4:3 / 3:4 : keep the SHORTER of (output_target_width, output_target_height) and recompute the longer side from this AR. Multiple-of-padding rounding still applies downstream. |
| output_resize_to_target_size | BOOLEAN | true | Force output to a specific resolution for sampling. |
| output_target_width | INT | 51264–16384 | — |
| output_target_height | INT | 51264–16384 | — |
| output_padding | COMBO | 32 | 8 options: 0, 8, 16, 32, 64, 128, +2 |
| device_mode | COMBO | gpu (much faster) | 2 options: cpu (compatible), gpu (much faster) |
| wan_align_multiple | INT | 161–256 | Force final crop W/H to multiples of this (Wan VAE patchify; 16 recommended). |
| wan_temporal_smooth_frames | FLOAT | 0.00–64 | Gaussian smoothing of mask along time axis (frames). 0 disables. |
| wan_stable_crop | BOOLEAN | true | Use a single union bbox across all frames (Wan replacement-mode). |
| wan_mask_polarity | COMBO | regenerate_subject | regenerate_subject: mask=1 -> regenerate (lquesada). preserve_subject: mask=0 -> regenerate (Wan2.2 replacement: mask=1 keeps environment). |
| inpaint_mask_mode | COMBO | hard_binary | What the inpaint sampler sees: hard_binary (crisp), slight_feather (gentle), soft_blend (very soft). |
| stitch_blend_mode | COMBO | gaussian | How the result is composited back: gaussian, edge_aware (Sobel), laplacian_pyramid, frequency_blend, video_stable. |
| blend_radius | INT | 321–256 | Feather radius for the stitch blend mask (independent of mask_blend_pixels). |
| video_stable_temporal_sigma | FLOAT | 3.00–10 | [video_stable only] Temporal Gaussian sigma in frames. 3.0 ≈ 9-frame window. Higher = smoother but laggier on fast motion. 0 = off. |
| video_stable_dilate_px | INT | -1-1–128 | [video_stable only] Pixels to push the blend zone into background BEFORE feathering. -1 = derive from blend_radius. 16-32 typical. |
| video_stable_blur_sigma | FLOAT | -1.0-1–128 | [video_stable only] Spatial Gaussian sigma for the wide feather. -1 = derive from blend_radius (×0.75). Match to dilate value. |
| fill_masked_area | COMBO | none | Fill masked region in the cropped image: none, edge_pad (Gaussian smear), neutral_gray, original. |
| maskopt | MASK | — | |
| optional_context_maskopt | MASK | — | |
| roto_qualityopt | BOOLEAN | false | Roto-Sync mode: tightens the inpaint seam for clean alpha edges. Forces laplacian_pyramid blend, halves blend_radius (min 4), and pre-erodes the inpaint mask by 1 px so the stitch falls just inside the subject. Safe to leave OFF for general inpaint; turn ON for compositing / roto / VFX work where boundaries must not bleed. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| stitcher | STITCHER | — |
| cropped_image | IMAGE | — |
| inpaint_mask | MASK | — |
| stitch_blend_mask | MASK | — |
| info | STRING | — |