Nodes/ComfyUI-SA-Nodes-QQ/Image Blend_GPU (QQ)
ComfyUI Node

Image Blend_GPU (QQ)

Composite layers with nine blend modes, no PIL round-trips

By siraxe·Created 11 months ago·Updated 2 days ago· 72
Image Blend_GPU (QQ)
  • background_image
  • layer_image
  • layer_mask
  • image
blend_mode
opacity100
invert_maskfalse

ComfyUI's built-in image compositing is workable but clunky - and for video frames it's painfully slow, because half the stock tools round-trip through PIL per frame. ImageBlend_GPU does the whole thing as tensor math on the GPU: background, a layer on top, nine blend modes, an opacity slider, and an optional mask. If you're compositing reference layers or VFX over generated Wan frames, this is the node that makes the difference between "I'll just wait" and "it's done."

It's part of siraxe/ComfyUI-WanVideoWrapper_QQ, the "(QQ)" Wan pack. It's a small utility, but it's the kind of small utility that keeps you inside one graph instead of exporting and compositing elsewhere.

How it works

Everything stays in float32 tensors on whatever device your inputs are on. The blend modes are implemented directly as channel-wise tensor ops - multiply, screen, overlay (with a fast torch.where branch), add/subtract with clamping, absolute difference, min/max for darken/lighten - and the layer is then alpha-composited onto the background by opacity. That's it. No image library, no CPU hops, no per-frame Python loops.

The mask handling is worth a look. If you connect layer_mask (a [B, H, W] MASK), it's converted to a single-channel [B, H, W, 1] and used to gate the layer; a single still mask is broadcast across a batch of frames, and if the mask batch is shorter than the frame batch, the last mask frame is repeated. invert_mask flips it (1 − mask). No mask connected means full-opacity compositing - the layer shows through as if opacity were 100, and opacity becomes your only fade control. Batch sizes mismatch? It computes max_frames and pads/truncates so a multi-frame layer can sit over a multi-frame background.

Inputs and outputs that matter

  • background_image - the base IMAGE.
  • layer_image - the IMAGE you're compositing on top.
  • blend_mode - normal, multiply, screen, overlay, add, subtract, difference, darken, lighten.
  • opacity - 0–100, the layer's overall strength.
  • layer_mask + invert_mask - optional gating.

Output is a single image IMAGE, same shape discipline as the inputs (sizes are matched internally).

Installation

cd ComfyUI/custom_nodes
git clone https://github.com/siraxe/ComfyUI-WanVideoWrapper_QQ.git

Restart ComfyUI (or ComfyUI Manager → "WanVideoWrapper_QQ"). No extra dependencies - pure torch, and the pack's requirements.txt is empty. Post-v1.3.4, delete any lingering wanwrapper_qq folder from before the pack renamed to ComfyUI-SA-Nodes-QQ.

Common issues

The traps are all in the numbers. opacity is an integer 0–100, and "normal" mode with no mask at opacity 100 just produces the layer - if your layer looks like it replaced the background entirely, that's expected, not a bug; drop opacity or add a mask. Mask order matters: it gates the layer, not the background, so a mask meant to protect the background will do the opposite. And resolution differences are handled by resizing, but extreme mismatches (a 256px layer on a 2K background) will look soft - pre-resize if you care about sharpness.

CategoryWanVideoWrapper_QQ/image

Inputs (6)

NameTypeDefaultDescription
background_imageIMAGE
layer_imageIMAGE
blend_modeCOMBO9 options: normal, multiply, screen, overlay, add, subtract, +3
opacityINT1000–100
layer_maskoptMASK
invert_maskoptBOOLEANfalse

Outputs (1)

NameTypeDescription
imageIMAGE