Paired Image Loader
Load before/after pairs from two folders, in sync
- output_image
- source_image
- filename
A/B comparison workflows live on pairs: here's the source scan, here's what the model did to it. Keeping those two images in lockstep across a whole folder is a chore - they're usually in different directories (originals/ and outputs/), with names that only loosely match, and one side always has more files than the other. PairedImageLoader is built for exactly this: point it at a source folder and an output folder, and each run it hands you the matching before/after pair as two synchronized IMAGE outputs.
Inputs: source_dir and output_dir (the two folders), reverse (swap which folder is treated as source), and strip_trailing_numbers, whose tooltip says it plainly: Strip trailing " (n)" suffixes before matching. That toggle is the one that saves the day, because image processors love producing photo (1).png, photo (2).png while the originals are photo.png, photo_01.jpg - and by stripping the (n) before matching, the node pairs them on the true base name instead of failing to find a match.
Outputs are output_image, source_image, and filename. source_image is whatever lives in the source folder, output_image is its partner, and filename is the shared base name. Every run advances to the next pair in natural-sort order, so running the graph repeatedly walks the folder set without you touching anything. It also carries state carefully - the match list is keyed by the two directories and the strip flag, so switching folders doesn't desync the pointer.
Where this shines is QA loops: feed the pair into a ComparisonGate or a side-by-side preview, eyeball source-vs-result, and iterate. Because both images arrive together with a shared filename, your save node can write photo__restored.png next to photo.png and the pairing survives on disk too.
Install
Manager → search "PortraitUtils", or:
cd ComfyUI/custom_nodes
git clone https://github.com/heyburns/PortraitUtils
Restart. PIL + pathlib; no extra deps.
Common issues
- Pairs don't match up - filenames differ beyond the
(n)suffix (e.g. one side has a prefix the other doesn't). The matcher is basename-based; fix the naming on one side or match in a pre-step. - "No pairs found" - either folder is empty, or the basenames genuinely don't overlap. Try
strip_trailing_numberson. - Source and output look swapped - flip
reverse. That's literally what it's for. - It loads the same pair twice in a row - the index advances on each execution; if the graph re-executes the loader before the comparison branch finishes, you'll see repeats. That's a graph-timing thing, not a loader bug.
If you do before/after passes at all - and every photo-restoration pipeline should - this removes the most tedious part of the loop.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| source_dir | STRING | — | |
| output_dir | STRING | — | |
| reverse | BOOLEAN | false | — |
| strip_trailing_numbers | BOOLEAN | false | Strip trailing " (n)" suffixes before matching. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| output_image | IMAGE | — |
| source_image | IMAGE | — |
| filename | STRING | — |