# Crop and Stitch makes ComfyUI inpainting sample only the masked area

> Two ComfyUI custom nodes split an inpainting job in half: one crops the image around the mask, you sample the crop with any standard workflow, and the other stitches the result back without touching the unmasked pixels. The payoff is speed, a controllable context area, and the ability to upscale before sampling, at the cost of a parameter list that rewards reading it.

**lquesada/ComfyUI-Inpaint-CropAndStitch** — ComfyUI nodes to crop before sampling and stitch back after sampling that speed up inpainting

- Repository: https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch
- Stars: 1,210 · Forks: 85
- Language: Python
- License: GPL-3.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/lquesada-comfyui-inpaint-cropandstitch

## Two nodes and a gap between them

ComfyUI-Inpaint-CropAndStitch is a pair of ComfyUI custom nodes, and the whole design is the gap between them.

The first node, Inpaint Crop, crops the image around the masked area, optionally with a context area that marks all parts relevant to the context. It also takes care of pre-resizing the image if desired, extending it for outpainting, filling mask holes, growing or blurring the mask, cutting around a larger context area, and resizing the cropped area to a target resolution.

The cropped image is then used in any standard workflow for sampling. It can even be rescaled up with any model, keeping the aspect ratio, and hiRes fixed, and the result will be retrofitted into the original image. The second node, Inpaint Stitch, stitches the inpainted image back into the original without altering the unmasked areas.

So the workflow is crop, sample, stitch, and the sampling step is yours to design. That is the important architectural point: this is not an inpainting node that hides the model behind it, it is a preparation step and a composition step with a standard sampler in between. You can put a controlnet, a different checkpoint, a different scheduler, whatever your workflow does, between the two nodes.

The audience is a ComfyUI user, and the project is installed the way ComfyUI custom nodes are, either through ComfyUI-Manager or by cloning into the custom_nodes/ directory. The package is published to the Comfy Registry under the publisher id lquesada, and the version in the project metadata is 3.0.17. The licence is GPL-3.0, and the copyright runs from 2024 to 2026 for Luis Quesada Torres.

## Why sampling a crop is faster and more faithful

The advantages the project lists are seven, and they are the argument for the design.

It is much faster than sampling the whole image. That is the obvious one: the diffusion model spends its time on pixels, and if only the masked region matters, the rest is work for nothing. On a large image with a small mask, the saving is most of the compute.

It enables setting the right amount of context from the image so the prompt is more accurately represented in the generated picture. This is the one that matters for quality. A diffusion model has no concept of what is outside the frame, so if you sample a tight crop, it invents the surroundings, and what it invents may not match the image it is being pasted into. A crop with a deliberate context region gives the model enough of the surrounding scene to be consistent with it.

It enables upscaling before sampling to generate more detail, then stitching back into the original picture. In other words, the small region is enlarged, the model paints detail at the higher resolution, and the result is composited back at the original scale.

It enables downscaling before sampling if the area is too large, in order to avoid artifacts such as double heads or double bodies. That is a very specific failure mode and it is worth understanding: a model asked to repaint a large area tends to reinterpret the whole thing, so a shirt becomes a different shirt and a head becomes a second head. Shrinking the region first removes the ambiguity.

It enables forcing a specific resolution, for example 1024 by 1024 for SDXL models. Modern models are trained at a particular resolution and behave differently outside it, so being able to hand the sampler exactly the resolution it expects is a real capability.

And it does not modify the unmasked part of the image, not even passing it through VAE encode and decode. This is the claim that separates it from an ordinary inpainting workflow. Any pixel outside the mask that goes through the VAE is changed slightly by the encode and decode round trip, because the VAE is lossy. Leaving those pixels untouched is not just faster, it is the difference between an image that looks edited and an image that looks untouched.

It also takes care of blending automatically, which is what the mask_blend_pixels parameter is for.

## The parameters, and the two that decide the result

The parameter list is long, and the documentation describes each one in a sentence. A few of them carry most of the behaviour.

context_from_mask_extend_factor sets the context area by a factor of the size of the mask. A value of 1 means do not grow, and 2 means grow by the same size of the mask in every direction. The higher the value, the more area is cropped around the mask, which means the model sees more of the image and has more to be consistent with, at the cost of a slower sample. This is the dial that trades speed against fidelity, and it is the one to spend time on.

mask_blend_pixels grows the stitch mask and blurs it by the given number of pixels, so the stitch is slowly blended and there are no seams. A hard edge between the generated region and the original is the classic inpainting giveaway, and this is where the softness comes from.

mask_hipass_filter ignores mask values lower than the value you specify. The explanation is practical rather than theoretical: sections of the mask that are almost 0, in other words almost black, are treated as masked, and that leads to confusion because the user believes the area is not really masked while the node considers it masked.

The mask modifiers follow. mask_fill_holes marks fully enclosed areas as part of the mask, whether the holes are small or large. mask_expand_pixels grows the mask by a number of pixels. mask_invert fully inverts the mask, keeping what was masked instead of removing what was marked, which is the difference between paint and erase.

Then there is the resolution control. preresize offers to resize the input image before any cropping, either to ensure a minimum resolution, a maximum resolution, or both, so that any input image arrives at the crop in a known state. output_resize_to_target_size forces the cropped image to a specific resolution, which may involve resizing and extending beyond the original image, and the stitch node reverts those changes to blend it back into place. output_padding ensures the cropped width and height are a multiple of a given value, because models require images padded to 8, 16 or 32 to work properly.

And two resizing algorithm choices, downscale_algorithm and upscale_algorithm, for the resize steps themselves.

## Outpainting extension, and what the factor means

The extend_for_outpainting parameter deserves a separate reading, because its semantics are unusual and easy to get backwards.

It shows options to extend the mask in any or all directions, up, down, left and right, by a certain factor. A factor greater than 1 extends the image, and the documentation gives the example that 2 extends the image in a direction by the same amount of space the image takes. A factor less than 1 crops the image, and 0.75 removes 25% of the image in that direction.

So this is not an absolute pixel offset. It is a proportion of the current extent of the image in that direction, which means the same value behaves differently on a tall image and a wide one, and it means that a value of 1 is the neutral setting, leaving the frame as it is.

This is what makes outpainting possible with the pair of nodes. The mask is extended beyond the original frame, the crop then includes area that does not exist yet, the model generates into it, and the stitch puts it back. The image is extended rather than the mask being clipped to the frame, which is what a normal inpainting workflow cannot do at all.

The same idea appears in output_resize_to_target_size, where forcing a resolution may involve extending beyond the original image, and the stitch node reverts that so the result blends back into place. In both cases the extension is temporary and local to the crop, which is the whole point of the crop and stitch arrangement: the model works on a canvas that can be bigger than the picture, and the composition step decides what survives.

For the resolution constraint, the documentation names 1024 by 1024 for SDXL models as the case that motivates it, and the model requirements in the workflow examples are consistent with that: the Flux example needs the controlnet inpainting beta, the GGUF text encoders and the VAE, and the large resolution example uses a 4x upscaler with a hiRes fix on top of the sampled crop before the stitch.

## Installing the nodes and running the examples

Installation is the standard ComfyUI custom node procedure, with two routes. Use ComfyUI-Manager, or go to the custom_nodes/ directory and clone the repository:

```bash
git clone https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch.git
```

The repository ships three example workflows in an example_workflows/ directory, and the documentation says you can either download the JSON or drag and drop the screenshot of the workflow into ComfyUI.

The Stable Diffusion example inpaint_sd15.json inpaints by sampling on a small section of a larger image, upscaling to fit 512 by 512, then stitching and blending back into the original. It is the right one to start with because it needs no extra models.

The Flux example, inpaint_flux.json, uses Flux and requires the GGUF nodes, with a specific model set: the Flux Dev Q5 GGUF in models/unet/, the Flux 1 dev controlnet inpainting beta in models/controlnet/, the t5 GGUF Q3_K_L and the clip_l text encoders in models/clip/, and the ae VAE in models/vae/. Each of those is a separate download, so this example is a bigger commitment than the first.

The third example, inpaint_hires.json, uses SD 1.5 to sample on a section of the larger image, then upscales the sampled image four times using the 4x Ultrasharp model and applies a hiRes fix, then blends it back into the original image. That is the workflow that demonstrates the upscale before sampling advantage end to end.

One caveat on the documentation: the video tutorial linked from the readme is for the previous version of the nodes, though it still shows how to use them and the parameters are mostly the same. For a node pair whose parameters are the substance, that is worth knowing before you follow the video.

## The CPU and GPU test configurations

The repository carries a testing setup that is unusual for a ComfyUI custom node pack, and it explains the device_mode parameter.

There is a run_tests.sh script, a tests/ directory, a testimgs/ directory with the images the tests use, and two configuration files named testscpu.json and testsgpu.json. The split is the point: the same test suite runs on CPU and on GPU, with separate configurations for each.

That maps directly to the device_mode parameter, whose documentation gives the two options as cpu, which should always work but is slow, and gpu, which is much faster but may not work in all setups. The default is GPU, given the performance improvements.

For a custom node pack that a user might install on a machine without a suitable GPU, or on a laptop where they want to check the nodes work at all, the CPU mode is the escape hatch, and having it covered by the same test suite as the GPU path is the reason to trust it. The device_mode is also a warning embedded in the API: the default is the fast path, and the compatible path is the one that is always available.

The repository also carries a js/ directory, which in the ComfyUI world is where the front end side of a custom node lives, and the pyproject.toml carries the Comfy Registry metadata with the publisher id, the display name and an icon field that is currently empty.

The project is not archived, the last push was on 2026-09-23, and the repository has no GitHub releases, so the version to follow is the 3.0.17 in the project metadata, with the Comfy Registry and ComfyUI-Manager as the distribution channels.

## Conclusion

The Crop and Stitch nodes suit a ComfyUI user who inpaints large images and is sampling far more pixels than the mask needs, and they suit anyone who wants to upscale before sampling and blend the result back cleanly. They are the wrong choice if you want one node to do the whole inpainting, since the point of the design is that the sampling step in between is an ordinary workflow you control, and a poor match if you are unwilling to tune the context and blend parameters, because the defaults are a starting point rather than a finished look. Before using them, work through the SD 1.5 example workflow first, since it needs no extra models, and read the context_from_mask_extend_factor and mask_blend_pixels settings, which are the two that decide how the seam looks.

## FAQ

### What do the Inpaint Crop and Inpaint Stitch nodes do?

The Crop node crops the image around the masked area with an optional context region, handling pre-resizing, outpainting extension, mask hole filling and target resolution, and the Stitch node puts the sampled result back into the original image without altering the unmasked areas.

### Why is inpainting only the masked area faster?

A diffusion model spends its compute on pixels, so sampling only the region the mask covers avoids the rest of the image. The project also notes that the unmasked part is not passed through VAE encode and decode, so it stays bit for bit unchanged.

### What does context_from_mask_extend_factor do?

It extends the context area by a factor of the size of the mask, in every direction. A value of 1 means do not grow, and 2 means grow by the same size of the mask across every direction, so higher values give the model more of the surrounding image at the cost of a slower sample.

### How do I install the ComfyUI Crop and Stitch nodes?

Install through ComfyUI-Manager, or clone the repository into the ComfyUI custom_nodes/ directory. The repository ships three example workflows in example_workflows/, starting with the Stable Diffusion one since the Flux example requires the GGUF nodes and several model downloads.

## Sources

- [Issues](https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch/issues)
- [License: GPL-3.0](https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch/blob/main/LICENSE)
- [lquesada/ComfyUI-Inpaint-CropAndStitch on GitHub](https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch)
- [README](https://github.com/lquesada/ComfyUI-Inpaint-CropAndStitch/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lquesada-comfyui-inpaint-cropandstitch
