chx_Ksampler_inpaint
Crop, sample, and stitch back — inpainting as one node
- context
- latent_image
- latent_mask
- mask_stack
- sample_stack
- context
- image
- cropped_mask
- cropped_image
Masked inpainting has a settled best-practice shape in 2026: crop tight around the masked region, sample at a resolution that gives the small area real generation budget, then stitch the result back so nothing outside the mask ever gets touched. chx_Ksampler_inpaint builds that whole pattern - crop, sample, stitch - into one node instead of the four-or-five-node chain (crop node, sampler, composite node, careful VAE handling) it normally takes to do properly.
Why crop-and-stitch matters here
The reason this pattern won out over just running the whole image through a sampler with a mask is simple: if you sample the full frame, unmasked pixels can shift slightly even when you don't want them to, and a small masked region gets a tiny fraction of your resolution budget to work with. Cropping tight around the mask, upscaling that crop to a working resolution, sampling only that, and pasting the result back guarantees the rest of the image is untouched and gives the masked area far more pixels to generate detail into - a 64px eye gets real generation resolution instead of a sliver of a 1024px frame.
The inputs and outputs that matter
contextandlatent_image(the base image to inpaint into) - required, along withseed.denoise(default 0.3) - how strongly the masked region gets regenerated. This node's default is already tuned toward "moderate detail fix" rather than "generate something entirely new" - push it toward 0.6–0.8 if you want a bigger change in the masked area, keep it low for subtle corrections.work_pattern-ksampler(default; actually run the sampler) oronly_adjust_mask, which is genuinely useful while you're setting up: it lets you preview and tune the crop/mask region without spending a sampling pass on every adjustment.crop_mode-no_crop,no_scale_crop(default), orscale_crop_image, controlling whether and how the region gets resized before sampling.long_side(default 512) - the working resolution the cropped region gets scaled to before sampling. This is your generation-budget dial: bigger means more detail spent on the masked area, at the cost of speed.expand_width/expand_height- pad the crop beyond the mask's tight bounding box, so the model has surrounding context rather than sampling right up to the mask edge.out_smoothness(0–150, default 2) - feathers the mask edge on the way back in, the same idea as mask blur in any inpainting workflow: too low leaves a visible seam, too high bleeds the change past where you wanted it.- Optional
latent_mask,pos(a positive prompt specific to the inpaint region), plusmask_stackandsample_stackfor chaining in the pack's other mask/sampling modifier stacks.
Outputs: context, the stitched-back full image, plus cropped_mask and cropped_image - the intermediate crop, exposed in case you want to inspect or further process just the working region before it's composited back.
Installing it
Through ComfyUI Manager: search ComfyUI-Apt_Preset, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/cardenluo/ComfyUI-Apt_Preset.git
then install.bat on Windows for dependencies, restart. This node needs nothing beyond your base checkpoint and VAE - no extra model downloads specific to it.
Common issues
Detail near the mask edge looks mismatched or scaled oddly. Try only_adjust_mask first to check your crop and expand values before spending a real sampling pass - a too-tight crop with no expand_width/expand_height padding gives the model no surrounding context to blend into.
Visible seam around the inpainted region. Increase out_smoothness. The default of 2 is quite low; most inpainting workflows land somewhere in the 4–12px-equivalent range before the seam disappears.
Change is too subtle, or too aggressive. That's denoise. 0.3 (the default) is a moderate-fix setting - for a bigger change, push it up; for a barely-there correction, pull it down toward 0.1–0.2.
latent_image is typed IMAGE, not LATENT - mismatched wiring. This node takes a decoded image for its main input, not a latent tensor, despite the name. Feed it a normal image (from a loader, or a previous sampler's decoded output), not a raw latent.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| context | RUN_CONTEXT | — | |
| latent_image | IMAGE | — | |
| seed | INT | 00–18446744073709550000 | — |
| denoise | FLOAT | 0.300–1 | — |
| work_pattern | COMBO | ksampler | 2 options: ksampler, only_adjust_mask |
| crop_mode | COMBO | no_scale_crop | 3 options: no_crop, no_scale_crop, scale_crop_image |
| long_side | INT | 51216–9999 | — |
| expand_width | INT | 00–2048 | — |
| expand_height | INT | 00–2048 | — |
| out_smoothness | INT | 20–150 | — |
| latent_maskopt | MASK | — | |
| posopt | STRING | — | |
| mask_stackopt | MASK_STACK2 | — | |
| sample_stackopt | SAMPLE_STACK | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| context | RUN_CONTEXT | — |
| image | IMAGE | — |
| cropped_mask | MASK | — |
| cropped_image | IMAGE | — |