Inpaint Crop (Artify)
Crop it down, inpaint big, stitch it back — Inpaint Crop (Artify)
- image
- mask
- optional_context_mask
- stitcher
- cropped_image
- cropped_mask
Masked inpainting's one remaining superpower is that the pixels you didn't touch stay exactly as they were. Inpaint Crop (Artify) is the first half of the workflow that makes that a structural guarantee rather than a discipline: crop a region around your mask, run any model on just that region at full budget, then let its sibling node paste the result back. The unmasked part of your image never goes through the VAE at all.
This is the crop-edit-stitch pattern made standard by lquesada's ComfyUI-Inpaint-CropAndStitch - the KB calls it the 2026 hybrid, the way people keep the mask but run a modern editor like Flux Fill or Qwen-Image-Edit inside it. The Artify version is a deliberate simplification of that reference: no pre-resize stage, no outpainting/extend controls, no forced output target size. You hand it an image and a mask, it hands you a crop and a mask sized for the model, plus a stitcher bundle that remembers where everything goes.
How it works
The crop is computed in stages, and they're worth knowing because the defaults are usually right but the failure modes are not:
- Mask prep: fill enclosed holes in the mask (on by default), expand edges by
mask_expand_pixels, optionally invert so the unselected region becomes the target, then apply a hipass threshold so faint mask values are ignored. - Context: it takes the bounding box of the (prepped) mask, grows it by
context_from_mask_extend_factor(default 1.2) so the model has surroundings to work with, and unions inoptional_context_maskif you want to force extra area in. min_context_megapixels: grows the context to hit a minimum area while preserving the input image's aspect ratio and staying inside the image. If the image is too small to reach the target, it uses the largest context that fits.- Grid snap: the crop dimensions are internally aligned to an 8px grid. That bit is there to stop latent-rounding mismatch between your crop and the model's output - the changelog for this pack is basically a history of fixing 1-pixel drift, and this is the structural fix.
Inputs that matter
mask- optional on paper, but obviously bring one. With no mask the whole image becomes "context" and you just get a full-frame crop, which is useful for testing and nothing else.mask_expand_pixels- padding around the mask so the edit has room to blend; start around the size of the feature you're fixing.mask_blend_pixels(default 32) - the blend radius used at stitch time, so the seam disappears.context_from_mask_extend_factor(default 1.2) - how much surrounding scene the model gets to see.min_context_megapixels- bump this if your crop is too small for the model to make sense of (a tiny eye crop with nothing around it hallucinates).device_mode- defaults togpu (much faster), with a CPU fallback.
Outputs and wiring
Three outputs, two of which matter immediately:
cropped_image- feed this to your model (img2img / inpainting conditioning / edit model).cropped_mask- feed alongside it as the model's mask input.stitcher(typeSTITCHER) - keep it and wire it straight into Inpaint Stitch (Artify) after sampling. It carries the original canvas, the crop geometry, and the blend mask.
The shape of the workflow is simple: crop → model → stitch.
Install
Same tiny pack as Image Resize (Artify), no real dependencies. Install via ComfyUI Manager (search ComfyUI-Artify), or clone:
cd ComfyUI/custom_nodes
git clone https://github.com/ArtifyGames/comfyui-artify.git
Restart ComfyUI and refresh the page.
Gotchas
- Batches: if a batch of images produces different crop sizes, the node raises an error - process items individually or make sure your masks produce consistent crops.
- The stitcher is a chain, not a ticket: crop → model → stitch in one run. Don't crop, run something unrelated, and then try to stitch a different image later; the geometry will be stale.
- Small mask, small crop: that's the point. A 64px eye gets 1024px of generation budget and gets pasted back - the "only-masked detail at full resolution" trick the KB says no whole-frame editor can match.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image to crop for inpainting. | |
| downscale_algorithm | COMBO | bilinear | Algorithm used when stitched content must be downscaled to fit the crop window. |
| upscale_algorithm | COMBO | bicubic | Algorithm used when stitched content must be upscaled to fit the crop window. |
| mask_fill_holes | BOOLEAN | true | Fill enclosed holes in the mask before computing context. |
| mask_expand_pixels | INT | 00–16384 | Expand mask edges by N pixels before context detection. |
| mask_invert | BOOLEAN | false | Invert mask so unmasked regions become the inpaint target. |
| mask_blend_pixels | INT | 320–512 | Blend radius (in pixels) used for stitching transitions. |
| mask_hipass_filter | FLOAT | 0.100–1 | Ignore mask values below this threshold. |
| context_from_mask_extend_factor | FLOAT | 1.201–100 | Grow mask-derived context area by this factor. |
| min_context_megapixels | FLOAT | 0.000–16 | Minimum context area in megapixels. Grows context while preserving input image aspect ratio. |
| device_mode | COMBO | gpu (much faster) | Run crop math on CPU (safe) or GPU (faster). |
| maskopt | MASK | Primary inpainting mask. | |
| optional_context_maskopt | MASK | Extra mask area to force-include as context. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| stitcher | STITCHER | — |
| cropped_image | IMAGE | — |
| cropped_mask | MASK | — |