ComfyUI Node

AP Image Mask Stitch

Put the inpainted crop back — the node that remembers where the crop came from

By adampolczynski·Created 6 months ago·Updated 6 months ago· 1
AP Image Mask Stitch
  • original_images
  • inpainted_images
  • stitch_data
  • stitched_images
blend_with_masktrue
feather0
interpolationbilinear

The second half of the crop-and-stitch inpaint pair. AP Image Mask Inpaint Crop cut a region out and handed you stitch_data; this node takes your inpainted result, reads that metadata, and places it back into the original frame at exactly the right position. It's the "put it back without a seam" step, and it's where a crop-based inpaint workflow either looks seamless or looks like a pasted sticker.

Why is this a real problem and not a trivial paste? Because the inpainted crop rarely lines up perfectly - your inpaint model might return a slightly different size, the crop might have been upscaled to a target resolution for better detail, and the boundary between the repaired region and the untouched original is exactly where artifacts show up. The stitch node has to resize the inpainted crop back to the original crop size, composite it into the frame, and blend the edges so the transition is invisible.

The mechanism

It takes three required inputs: original_images (the untouched frames), inpainted_images (your model's repaired crops), and stitch_data (the AP_STITCH object from the crop node). The stitch metadata carries the per-frame crop offsets, sizes, and batch alignment, so the node knows, for each frame, where its inpainted crop belongs. It resizes the inpainted crop back to the original crop geometry, composites it into the original frame, and - with blend_with_mask=true (the default) - blends along the mask boundary so the repaired region fades into the original instead of hard-cutting. feather (0–64) controls how wide that fade is; the README's advice is to start low and only raise it when a seam is visible. interpolation picks the resize method for crops that came back at a different size.

Inputs that matter

  • stitch_data - the return ticket from the crop node. This is the input that makes the whole thing work, and the only one with no knob: wire it and the node knows where everything goes.
  • blend_with_mask - default true; turn it off if you want a raw paste (rarely what you want, but there for edge cases).
  • feather - the seam-hiding dial. Start at 0, raise only when you see the boundary.

Outputs

stitched_images - the full frames with the inpaint placed back. That's it. Feed to a preview, save, or the next stage of your video pipeline.

Installing it

Pack-wide install: ComfyUI Manager (search "AP_OpticalFlow"), or

cd ComfyUI/custom_nodes
git clone https://github.com/adampolczynski/ComfyUI_AP_OpticalFlow
python -m pip install -r custom_nodes/ComfyUI_AP_OpticalFlow/requirements.txt

Restart. Dependency is torchvision>=0.15.

The troubleshooting that matters

If your stitched result shows a visible seam: first raise feather a little (the README's explicit guidance - start low, increase only when the seam is visible), then check padding on the crop side - a crop with too little context is the root cause of many seams. If the inpaint appears offset - placed in the wrong spot - that's a stitch_data mismatch: either you rewired the wrong crop's metadata or you changed the source frames between crop and stitch. The metadata only describes the frames it was computed on. And for video, keep crop_universal_box=true on the crop node; a per-frame drifting crop box is a recipe for a stuttery, jittering inpaint region that no feather setting will fix.

CategoryAP_OpticalFlow

Inputs (6)

NameTypeDefaultDescription
original_imagesIMAGE
inpainted_imagesIMAGE
stitch_dataAP_STITCH
blend_with_maskBOOLEANtrue
featherINT00–64
interpolationCOMBObilinear3 options: bilinear, bicubic, nearest

Outputs (1)

NameTypeDescription
stitched_imagesIMAGE