ARC Composite
Paste your AI edits back without wrecking the original
- generated_image
- source_image
- edit_mask
- image
- composite_mask
- report
- debug_view
If you've ever sent an image to Nano Banana, GPT Image, or Gemini to "just change the shirt," you know the pain this node exists to fix. The API doesn't change the shirt. It regenerates the whole frame, and whatever it decided to "helpfully" alter along the way - the background, the text on the poster, your friend's face in the corner - is now subtly wrong. There's no bit-identical-untouched guarantee from these models the way there is with local mask-based inpainting.
ARC Composite is the fix bolted onto the end of that pipeline: a deterministic, pure-PyTorch paste-back step that keeps the source image everywhere outside your edit mask and feathers the edit in only where you asked. It's the "always composite after you edit" rule the inpainting crowd has preached for years, adapted for the API era where the whole image comes back instead of just the masked patch.
How it works
Feed it three things - the edited image the model returned, the original source, and an authored edit mask - and it builds a composite mask, grows it, feathers its edges, and alpha-blends: source * (1 - alpha) + edit * alpha. Outside the mask you get your original pixels back, untouched. No API, no key, no model of its own; it doesn't even care which model made the edit.
The interesting bit is that the mask doesn't have to be just yours. The node can also detect actual changes by computing the per-pixel RGB distance between source and generated, and threshold it. That gives you three mask_mode choices: "ARC Mask" (only your authored mask), "Detected Changes" (only what actually changed), and "ARC Mask + Detected Changes" (union of both). The union mode is the real timesaver - it catches edits that bled outside your rough mask. Generated images are auto-resized to the source dimensions, since API outputs rarely match your canvas exactly.
Everything else is feathering and seam polish: edge_feather_px softens the transition (two cheap box-filter passes), seam_match shifts the generated image's colors toward the source in a ring just inside the seam so you don't get a visible tint step, and mask_grow_px dilates the working mask.
The inputs that matter
generated_image,source_image,edit_mask- required. That's the whole contract.change_sensitivity- threshold for difference detection. The direction is non-intuitive: low (near 0) catches even subtle changes; high (near 1) only catches strong ones. Default 0.2 is a decent middle.edge_feather_px(default 12) - where visible seams go to die. Raise it if the composite edge shows.seam_match(default 0.35) - color-matching strength at the border.
Outputs: image (the composite), composite_mask (the final working mask, handy for inspecting what got replaced), report (a text summary with the threshold, feather and pixel counts - wire it into a ShowText-style node and it tells you exactly what the node decided), and debug_view, a 2×2 source/generated/mask/result grid - but only when the debug toggle is on. Leave debug off and debug_view is a useless dummy tensor, so flip the toggle before you wonder why it's empty.
Install
Zero drama. ComfyUI Manager → search "ComfyUI-ARC-Composite", or:
cd ComfyUI/custom_nodes
git clone https://github.com/DHan315/ComfyUI-ARC-Composite
Restart ComfyUI. There are no dependencies - the pack's dependencies = [], and the whole node is torch (which ComfyUI already ships). No model files, no OpenCV, no hidden downloads. Find it as "ARC Composite" (category "ARC"). One license note: it's GPL-3.0, which only matters if you're shipping a product around it.
Where people get burned
This is a new, barely-installed pack, so there's no battle-tested folklore yet - but the failure modes are visible in how it's built. First and biggest: the edit must stay spatially aligned with the source. If the API cropped, reframed, or zoomed, a mask blend can't un-crop - you'll get ghosting or a double edge, and difference detection will just flag the whole frame. Reach for it when your edit model plays nice with a mask, not after it reinvented the composition.
Second, edit_mask is required even in "Detected Changes" mode - if you have no authored mask, feed it a black/empty mask and let detection do the work. Third, don't skip the report output when something looks off: it prints the actual threshold and mask coverage, which tells you in one glance whether detection misfired or your mask was just tiny.
It won't fix a bad edit. But it's the cheap deterministic half of the pipeline - the part that should never re-roll a generation.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| generated_image | IMAGE | — | |
| source_image | IMAGE | — | |
| edit_mask | MASK | — | |
| mask_mode | COMBO | ARC Mask | 3 options: ARC Mask, ARC Mask + Detected Changes, Detected Changes |
| change_sensitivity | FLOAT | 0.200–1 | — |
| mask_grow_px | INT | 00–256 | — |
| edge_feather_px | INT | 120–256 | — |
| seam_match | FLOAT | 0.350–1 | — |
| debug | BOOLEAN | false | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| composite_mask | MASK | — |
| report | STRING | — |
| debug_view | IMAGE | — |