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 (8)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | BHWC batch; every frame in it is saved. | |
| filename_prefix | STRING | AusBoss/image | Classic naming: prefix plus a counter that never overwrites, in ComfyUI's output folder. Subfolders are allowed. Ignored while exact_name is set. |
| format | COMBO | png | png saves everywhere. jxl lossless keeps every pixel bit-identical in a smaller file; it needs the optional pillow-jxl-plugin in ComfyUI's python and says so if it is missing. |
| save_metadata | BOOLEAN | true | On embeds the prompt and workflow (PNG text chunks; EXIF in jxl), so the file drags back into ComfyUI. Off writes a clean file with no workflow inside β for sharing without shipping the recipe. |
| exact_nameopt | STRING | Save under exactly this filename β no counter suffix. An image extension on the value is replaced by the chosen format's own, so 'photo123.jpg' saves as photo123.png and pairs with photo123.txt. Subfolders are allowed; a batch appends _001, _002β¦ since frames cannot share one name. Empty uses filename_prefix instead. | |
| on_existingopt | COMBO | overwrite | What an exact_name save does when the file is already there: overwrite replaces it (the usual reason to want an exact name), skip leaves it and moves on, error stops the run. Classic prefix saving never collides. |
| output_diropt | STRING | Where to save. Empty is ComfyUI's output folder; a relative path is a subfolder of it; an absolute path saves anywhere you can write β e.g. straight into a dataset folder. The node preview only shows files inside 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 image/caption pair training tools expect. Empty writes no sidecar. |
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. |