Image Composite Masked
Lay one image on another exactly where you want it — with a mask
- destination
- source
- mask
- IMAGE
The final step of almost every automated fix loop is a paste: you detected a face, re-rendered a clean version, and now you have to put it back on the original without wrecking everything around it. That's compositing, and it needs three things - a destination, a source, and a mask saying where the source is allowed to show. Image Composite Masked is the WAS Node Suite node that does it with a pixel position and a visible check, so you're not trusting that the paste landed blind.
WAS Node Suite is WASasquatch's MIT pack, around since the start of ComfyUI's custom-node scene and now 457 nodes in v3. This node lives under WAS Suite/Image/Process.
The inputs
destination- the picture being pasted onto. Its size and batch length rule the output; every frame gets composited the same way.source- the picture laid on top. If the batches differ in length, the source is repeated or trimmed to match the destination. Anything hanging past the right or bottom edge of the destination is simply cut off.xandy- where the source's top-left corner lands, in pixels from the destination's left and top. 0, 0 parks it in the corner.resize_source- default off, which places the source at its own size. Turn it on and the source is stretched to fill the whole destination frame first; x and y then only shove it off that full-frame position.mask(optional) - where the source shows through. White shows all of it, black none, and 0.5 blends the two evenly. It's scaled to the source's size, so you don't need to pre-match dimensions. Unconnected, the entire source is pasted, which makes the node a plain positioned composite.
The output is a single IMAGE: the destination with the source composited in, at the destination's size, batch length and channel count.
Why it's better than the naive paste
The node draws its own diagnostic band: destination beside result, with the source that went between them, plus a difference readout. So the two classic failure modes show up on the node instead of after a preview is wired downstream - a source dropped off the edge (you can see it hanging there) and a mask the wrong way round (the "difference" lights up where it shouldn't).
Mechanically it's straightforward compositing: alpha from the mask, source placed at x,y, mixed over the destination. Nothing exotic. The value is that the mechanics are visible, which matters because this node is usually the end of a long and expensive chain - the whole point of a mask-based composite is that only the repaired region changes and the rest of the frame stays pixel-identical.
Where it fits
You'll most often reach for it as the paste step in the detect → crop → re-render → paste loop that masking-detailing workflows use to fix faces and hands. Crop the bad region by mask, re-render it, then composite the fixed crop back over the original at the crop's original coordinates with a feathered mask hiding the seam. It also does ordinary jobs: putting a character onto a background at a chosen spot, or pasting a watermark region with a soft mask.
One caveat that trips people up: x,y and resize_source interact. If you resize the source to fill the frame, positioning is meaningless except to shove it partially off. If you don't resize, the source keeps its own aspect - a 2048px source pasted onto a 512px destination will mostly hang off the edge and get cut. Check sizes upstream when the result looks like only a corner of your source appeared.
Install
Standard WAS Node Suite: ComfyUI Manager, search "WAS Node Suite v3", or git clone https://github.com/WASasquatch/was-node-suite-comfyui into ComfyUI/custom_nodes and restart. Requires ComfyUI 0.14.0+ and Python 3.10+. No extra packages - v3 does its pixel work on torch and installs nothing, which spares you the dependency collisions v2 was famous for.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| destination | IMAGE | The picture the source is laid over. Its size and batch length are what come out, and every frame is composited alike. | |
| source | IMAGE | The picture being laid on top. It is repeated or trimmed to the destination's batch length, and whatever hangs off the right or bottom edge is cut. | |
| x | INT | 00–16384 | Pixels from the left of the destination to the source's left edge; INT. 0 sits it in the corner, 256 moves it 256 across. |
| y | INT | 00–16384 | Pixels from the top of the destination to the source's top edge; INT. 0 sits it in the corner, 256 moves it 256 down. |
| resize_source | BOOLEAN | false | Whether the source is stretched to the destination's whole frame first. `false` places it at its own size at x,y; `true` fills the frame edge to edge, and x and y then only push it off. |
| maskopt | MASK | Where the source shows through: white shows all of it, black none, 0.5 mixes the two evenly. Scaled to the source's size. Unconnected, the whole source is pasted. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | The destination with the source composited into it, at the destination's size, batch length and channel count. |