Donut Image Save
The WAS save node without the WAS install
- images
- images
- files
ComfyUI's stock SaveImage writes a PNG with an auto-incrementing counter and calls it a day. That's fine until you want WebP, or a filename pattern that actually means something, or the numbered-filename behaviour WAS Node Suite gave you - at which point you install a 200-node utility pack for one node.
Donut Image Save is that one node, extracted. The numbering is adapted from WAS Node Suite's naming module (MIT, credited in the repo), the pack's own workflow test saved a 1728 × 1344 WebP that matched the old WAS output byte-for-byte with the same settings, and the README's whole framing is "without a WAS dependency." If you migrated a workflow off WAS and want your old save behaviour back, this is the node.
How it works
It walks the batch one frame at a time and writes each to output/ or temp/ depending on root. Filenames are prefix + delimiter + a zero-padded counter - or counter-then-prefix if you flip filename_number_start. To keep numbering consistent across runs it scans the destination folder for the highest existing number matching that name pattern and continues from there, then opens files with exclusive creation (xb) so two concurrent runs can't land on the same filename. overwrite_mode changes that to a fixed name you rewrite every run.
Metadata goes in per format. For PNG it writes tEXt chunks containing the prompt and the extra PNG info, and stamps the DPI - that's the same channel ComfyUI's own saver uses, so dragging the file back onto the canvas still rebuilds the graph. For WebP it re-homes the same data into EXIF tags instead, and honours lossless_webp.
Two guards are worth knowing about because they're deliberate: the resolved filename_prefix has to stay inside the selected root (subfolders work via slashes, symlink escapes don't), and the delimiter can't contain a path separator.
Inputs
Wire images and then pick your settings. The ones a beginner actually touches:
filename_prefix- subfolders are legal here (portraits/run_a). Default isComfyUI.extension- png, jpg, jpeg, gif, tiff, webp, bmp. WebP is the reason most people are here.quality(1–100) andlossless_webp- for WebP,lossless_webpbeatsqualitywhen you care about fidelity, and costs you the file size savings you came for.filename_number_padding(4 by default) andfilename_number_start- padding is how you get_0001instead of_1.overwrite_mode- off by default. Turning it on means one predictable filename you can point a viewer at, and it will happily erase yesterday's render.embed_workflow- on by default. See below.
The rest - root, dpi, optimize_image, show_previews, filename_delimiter - are set-and-forget.
Outputs
images is an IMAGE passthrough, so you can chain a preview or a second saver after it, and files is a list of the written paths as STRINGs (useful for a text node or a filename-consuming downstream node). It's an output node, so the cache runs backward from it - it always executes.
Install
The node lives in the DonutNodes pack, so installing the pack gets you the saver:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
Or search DonutNodes in ComfyUI Manager. The pack's pip list is short and wheel-based (opencv-python-headless, scipy, matplotlib, psutil, tqdm, requests), and its stated policy is that it will not downgrade your shared NumPy or reinstall PyTorch - which is the right call, because one pack repairing itself by breaking your interpreter is how you get an evening of debugging.
Worth saying plainly: installing Donut doesn't uninstall WAS. If other workflows depend on it, they keep working; this node just means your save path doesn't.
Gotchas
WebP is a derivative, not an archive. The PNG chunk is the only place a ComfyUI graph round-trips. This node does stuff the generation data into WebP EXIF, but treat the PNG as your master and the WebP as the shareable copy - a lossy WebP of a good render should never be the only copy you kept.
Metadata is disclosure. The default is to bake your prompt, negative, seed, checkpoint names and the entire node graph into the file. That's the culture here, but if you'd rather not hand someone your private prompt style, flip embed_workflow off or start ComfyUI with --disable-metadata.
No A1111-style parameters block. This node writes the ComfyUI prompt and workflow chunks, not the flat Steps: / Sampler: / CFG scale: string CivitAI's uploader keys on for auto-linking models. If model auto-linking on upload matters to you, that's a different saver's job - post-processing tooling exists specifically to emit both.
JPEG converts to RGB. Any alpha or non-8-bit data is gone the moment you pick jpg. Obvious, easy to forget in a batch node.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| root | COMBO | 2 options: output, temp | |
| filename_prefix | STRING | ComfyUI | — |
| filename_delimiter | STRING | _ | — |
| filename_number_padding | INT | 41–9 | — |
| filename_number_start | BOOLEAN | false | — |
| extension | COMBO | 7 options: png, jpg, jpeg, gif, tiff, webp, +1 | |
| dpi | INT | 3001–2400 | — |
| quality | INT | 1001–100 | — |
| optimize_image | BOOLEAN | true | — |
| lossless_webp | BOOLEAN | false | — |
| overwrite_mode | BOOLEAN | false | — |
| embed_workflow | BOOLEAN | true | — |
| show_previews | BOOLEAN | true | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| files | STRING | — |