Save Image (FFMPEGA)
The preview node that also does side-by-side comparisons
- images_a
- mask
- image
- image_path
- mask_points
- mask
ComfyUI ships a Save Image node. This one exists because the FFMPEGA pipeline passes around two different things that both want to end up as a picture: IMAGE tensors, and paths to images already on disk. A mask overlay written by Load Video Path is a file, not a tensor, and the core save node can't do anything with it. This node takes either, shows a preview inline, and hands the result onward instead of dead-ending the graph.
The path case is the interesting one
images_a takes a tensor and saves it as PNG. image_path_a takes a string path and copies the file into ComfyUI's output directory - which is why the node's docstring calls it "zero memory cost." Nothing is decoded into a tensor at all. That's the right way to save a mask_overlay_path or any of the other file paths the pack's loader nodes produce, and it's the reason this node exists rather than you just using the core one.
Both inputs are dynamic: connect images_a and an images_b slot appears, then images_c, and so on. Same with image_path_a, image_path_b. Up to you how many.
Combining them is the actual feature
Once you've got two or more sources connected, layout decides what happens: auto picks a best-fit grid (two side-by-side, four in a 2×2), horizontal and vertical force a strip, grid forces a matrix, and none saves each source as its own file. panel_gap is the pixel gap between panels, defaulting to a stingy 4. Turn on label_panels and fill in labels - comma-separated, Original, Upscaled, Upscaled + detailer - and each panel gets a caption. labels only applies when label_panels is on, so if your captions don't show up, that's the switch you missed.
This is the node's real use in practice. Upscaler comparison is the classic: run the same input through two or three paths and put them in one image where you can actually see the difference instead of clicking between preview tabs and lying to yourself about which one is sharper. Same trick for background removal methods, or for an A/B on a colour grade.
The rest of the settings
filename_prefix defaults to FFMPEGA and supports ComfyUI's date formatting, e.g. %date:yyyy-MM-dd%, so a month of experiments doesn't pile into one flat folder. save_output on (default) copies into the output directory; off, you get the inline preview without a permanent file, which is genuinely useful when you're doing twenty test queues and don't want to clean up afterwards. overwrite off (default) auto-increments the filename counter instead of clobbering, which is the setting you want to leave alone.
Outputs are image (the tensor, or the loaded file, so you can keep going downstream), image_path, and two pass-throughs: mask_points and mask. Those exist so you can slot this node into the middle of a pipeline as a debug checkpoint without severing the mask wiring - they're forwarded as-is, not modified.
Install
ComfyUI Manager → search ComfyUI-FFMPEGA → Install, or:
cd ComfyUI/custom_nodes
git clone https://github.com/AEmotionStudio/ComfyUI-FFMPEGA.git
pip install -r ComfyUI-FFMPEGA/requirements.txt
Restart. No models, no downloads. The rest of the pack wants FFMPEG on PATH, but this node is mostly file copies - saving a path input doesn't decode anything.
Where people get burned
The path inputs don't accept pasted text from everywhere. image_path_a is a forceInput string - wire it from a node like Load Video Path, or you'll be typing absolute paths by hand and wondering why a relative one silently fails.
Panel labels skip when the count doesn't match. Provide three labels for two panels and you get a shrug, not an error. Keep the list in the same order as the connected slots.
It's an output node, so it always runs when it's in the graph. If you're using it purely as a preview and don't want files, save_output off is the correct setting rather than deleting the node and rewiring later.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| filename_prefix | STRING | FFMPEGA | Prefix for the saved image filename. Supports ComfyUI formatting like %date:yyyy-MM-dd%. |
| images_aopt | IMAGE | Image tensor input. When connected, saves the tensor directly as PNG. More slots appear automatically (images_b, images_c, ...) so you can stack several images for comparison. | |
| image_path_aopt | STRING | Path to an image file (e.g. mask_overlay_path from Load Video Path, or any PNG/JPG path). More slots appear automatically (image_path_b, ...) — connect several and set 'layout' to combine them. | |
| layoutopt | COMBO | auto | How to combine multiple connected sources. auto = best-fit grid (2 side-by-side, 4 in a 2x2, ...). horizontal/vertical/grid force a layout. none = save each source separately. |
| label_panelsopt | BOOLEAN | false | Draw a caption on each panel of a combined image using the comma-separated 'labels' field. |
| labelsopt | STRING | Comma-separated panel captions, e.g. 'Original, Upscaled'. Used only when 'label_panels' is on. | |
| panel_gapopt | INT | 40–128 | Pixel gap between panels in a combined image. |
| save_outputopt | BOOLEAN | true | When On, copies the image to ComfyUI's output directory. When Off, shows the inline preview without saving a permanent copy. |
| overwriteopt | BOOLEAN | false | If true, overwrite the output file if it already exists. Otherwise, auto-increment the filename counter. |
| mask_pointsopt | STRING | Optional upstream mask_points pass-through. Forwarded as-is to the mask_points output. | |
| maskopt | MASK | Optional upstream MASK pass-through. Forwarded as-is to the mask output. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| image_path | STRING | — |
| mask_points | STRING | — |
| mask | MASK | — |