Eses Image Compare
Stop squinting at side-by-side previews — drag a slider across your A/B test instead
- image_a
- image_b
- image_a
- diff_mask
Eses Image Compare is the node you reach for when you're A/B testing and tired of stacking two Preview Image nodes side by side, then moving your eyeballs back and forth like you're proofreading a contract. It overlays two images on top of each other and gives you a draggable slider that reveals one over the other, so differences show up as movement right at the boundary line. Wire checkpoint A into one input, checkpoint B into the other, and drag. No squinting, no tab-switching.
It's a viewer, not a generator - it changes nothing about your output. The whole contribution is making "did that LoRA actually change the face, or did the seed move?" answerable in two seconds. r/comfyui users describe it as the comparison tool that doesn't cost you performance, and that's accurate: all the comparison rendering happens in the browser, on the node's own JS, not on your GPU.
How it works
The mechanism is simple and worth knowing. On every execution the node base64-encodes the first frame of each connected image and pushes it to the frontend over ComfyUI's websocket (PromptServer), tagged with the node's id. The bundled js/image_compare.js picks that up and draws the overlay canvas with the slider, the A/B labels, and the resolution readout you see below the preview. In Python it only does two things: ship the images to the browser, and compute a difference mask. There are zero extra Python dependencies - it uses torch, numpy and PIL, all of which ship with a stock ComfyUI install. No model downloads, no requirements.txt, no API keys.
The inputs that matter
image_a(required, IMAGE) - the "before" or the reference. This is the one that passes through.image_b(optional, IMAGE) - the "after" or the variant. Leave it unconnected and the node behaves like a plain viewer: no slider, no diff mask.
The blend mode and the horizontal/vertical axis aren't graph inputs you wire - they're controls drawn on the node itself. The Blend Mode combo (normal, difference, lighten, darken, screen, multiply) is the part you'll actually touch. Difference is the one you'll live in: it zeroes out pixels that match and lights up everything that changed, which is how you catch the subtle stuff - a shifted hand, a re-rendered background, an upscaler that quietly redrew your subject's face.
What comes out
Two outputs. image_a is a passthrough, so the node can sit in the middle of a workflow instead of only at the end - hook the chain through it and the next node never notices anything happened. diff_mask is the interesting one: a grayscale MASK, computed in Python by converting both images to luma (standard 0.2126R + 0.7152G + 0.0722B weighting) and taking the absolute difference. It's not thresholded, so values range from 0 (identical) up toward 1 (totally different), and you can feed it into whatever MASK slot you like - threshold it, blur it, use it to drive later processing. The node is marked as an output node, so ComfyUI won't prune it even if nothing's connected below.
Installing it
Easiest route: ComfyUI Manager → search "Eses Image Compare" and install. Manual route, same as any pack:
cd ComfyUI/custom_nodes
git clone https://github.com/quasiblob/ComfyUI-EsesImageCompare
Restart ComfyUI and it appears under Eses Nodes/Image Utilities. That's it - nothing else installs. The README does ask you to read the LICENSE before using it, which is a fair ask and costs you thirty seconds.
When it bites you
Two traps, both worth knowing before they waste an afternoon.
The diff mask silently goes to zero if the images aren't the same size. The code only computes a real mask when image_a.shape == image_b.shape. Feed it a 1024 image and a 1344 image and you'll get back an all-black mask with no warning - so if your mask is suddenly empty, that's why. Resize one input to match the other first (ImageScale or similar).
It does not work in Nodes 2.0 mode. That's the author's own warning, right in the README. The preview relies on custom JS canvas rendering, and the Nodes 2.0 rewrite broke exactly that class of node - the same thing that temporarily took out the rgthree comparer in late 2025. If you're on Nodes 2.0 and the preview area is blank or missing, switch back to the legacy canvas rather than filing a bug.
One more minor quirk: the preview only shows the first frame of a batch, so it's really built for stills, not for scrubbing through video frames. For a free, dependency-free way to actually see what your changes did, though, it's hard to beat.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image_a | IMAGE | — | |
| image_bopt | IMAGE | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image_a | IMAGE | — |
| diff_mask | MASK | — |