Save Image π
PNG, lossless JXL, exact filenames, and captions that land beside the file
- images
- file_path
- images
Save Image π writes your batch to disk and it's tuned for the two jobs people actually fight the stock save node over: keeping a file's name, and pairing a caption next to it. The headline feature is exact_name. Give it photo123 and the image saves as exactly that filename - no counter suffix - so an edit, inpaint, or caption pass can write back over the source file and keep the filename the rest of your pipeline knows. Give it a non-empty caption and it writes a UTF-8 .txt sidecar with the same basename: photo123.png + photo123.txt, the exact image/caption pair that kohya, ai-toolkit, and OneTrainer all expect when they walk a training folder. That combo - exact name, sidecar caption - is the dataset-captioning pass in a single node.
The workflow-metadata story is worth knowing before you rely on it. By default save_metadata is on, which embeds the prompt and full node graph into the file (PNG text chunks; EXIF in JXL). That's what makes a saved image drag back onto the canvas and reconstruct its whole workflow - the file is the project file. Flip it off and you get a clean file with no recipe inside, for sharing without shipping your prompts. The pack even respects the server-level --disable-metadata flag, which overrides the widget for the whole instance.
How it works
filename_prefix gives you the classic behavior: prefix_00001_.png, prefix_00002_.png... with an auto-incrementing counter that never overwrites, subfolders allowed, landing in ComfyUI's output/ folder. The exact_name path is the opposite: exactly that name, with on_existing deciding the collision (default overwrite; skip leaves it and moves on; error stops the run). A batch under an exact name appends _001, _002β¦ since frames can't share one filename, and any image extension you type is replaced by the format's own, so photo123.jpg saves as photo123.png and pairs with photo123.txt. output_dir defaults to the output folder; a relative path is a subfolder of it; an absolute path writes anywhere you can, like straight into a dataset folder. format is png (saves everywhere) or jxl lossless - bit-identical pixels in a smaller file, but it needs the optional pillow-jxl-plugin in ComfyUI's Python, and the node tells you by name if it's missing.
Outputs: file_path (the absolute path of the first file this run saved, empty if everything was skipped - wire it to a node that wants the file itself) and images (the input batch, unchanged, so you can save mid-graph and keep wiring). It's an output node that always runs - the pack forces it via the IS_CHANGED always-rerun trick, because a saver's job is the side effect.
Install
ComfyUI Manager is the easy route: search for ComfyUI-AusBoss under Custom Nodes and hit Install, then restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/ausboss/ComfyUI-AusBoss.git
Restart ComfyUI and Save Image π sits under π AusBoss/Image. The pack itself has no required extra dependencies; JXL is the one optional add (pip install pillow-jxl-plugin into ComfyUI's Python) and the node says so if you pick the format without it. Minimum ComfyUI 0.27.1, and hard-refresh with Ctrl+Shift+R after frontend updates.
Common issues
Three gotchas. First, the node preview only shows files inside the output folder - if you write to an absolute output_dir elsewhere, you get a path back, not a preview thumbnail. Second, exact_name + overwrite will clobber a file of the same name, which is the point, but double-check it isn't your only copy of something. And third, metadata travels with the format: PNG carries the workflow, but if you strip it or a host re-encodes it, the graph is gone - keep the original PNG as your master and share copies. For a training set, pair exact names with captions and you'll never hunt for which .txt goes with which image.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | BHWC batch; every frame in it is saved. | |
| filename_prefix | STRING | AusBoss/image | The local filename, with optional subfolders: the name tags (date, time, size, counter, batch) are appended to it. Ignored while filename is linked or exact_name is set. |
| format | COMBO | png | png saves everywhere and preserves alpha. webp lossless is usually smaller than png, alpha kept. jxl lossless is the most compact; it needs the optional pillow-jxl-plugin in ComfyUI's python and few browsers preview it. |
| save_metadata | BOOLEAN | true | On embeds the prompt and workflow (PNG text chunks; EXIF in webp and jxl), so the file drags back into ComfyUI. Off writes a clean file with no workflow inside - for sharing or datasets. |
| exact_nameopt | STRING | Save under exactly this filename - no tags. An image extension on the value is replaced by the chosen format's own. Subfolders are allowed; a batch appends _001, _002... Empty composes the name from filename_prefix instead. A linked filename input takes precedence. | |
| on_existingopt | COMBO | overwrite | What a save that lands on an existing file does: overwrite replaces it, skip leaves it, error stops the run. Only reachable with the counter off, an exact name, or a linked filename - the counter never collides. |
| output_diropt | STRING | Subfolder of ComfyUI's output folder to save into, such as sets/portraits; created if missing. Empty saves to the output folder itself. Save Image never writes outside the output folder. | |
| captionopt | STRING | When not empty, writes this text as a UTF-8 .txt sidecar with the same basename as each saved image. The caption_text input takes precedence. | |
| filenameopt | STRING | Exact filename from upstream (a Load Image name, a caption tool's id). Its image extension is replaced by the chosen format's; no tags are added; a batch appends _001, _002... A linked but empty value stops the run rather than saving under a made-up name. | |
| caption_textopt | STRING | Caption from upstream: saved as a .txt in the same folder with the same name as the image (portrait.png -> portrait.txt). Empty writes no sidecar. | |
| name_counteropt | BOOLEAN | true | Append the next free five-digit number. On is collision-safe; off reuses the same path and replaces an existing file. |
| name_dateopt | BOOLEAN | false | Append the local save date as YYYY-MM-DD. |
| name_timeopt | BOOLEAN | false | Append the local save time as HH-mm-ss. |
| name_sizeopt | BOOLEAN | false | Append the image dimensions as WIDTHxHEIGHT, such as 1024x1024. |
| name_batchopt | BOOLEAN | false | For an image batch, append b001, b002... so each image's position in this run is visible. A single image is unchanged. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| file_path | STRING | Absolute path of the first file this run saved (empty when every file was skipped), for downstream nodes that want the file itself. |
| images | IMAGE | The input batch, unchanged - save first, keep wiring. |