πΌ Save Image
Three formats, injected metadata, and one trap on by default
- image
- watermark
- Saved Paths
- PNG Path
- JPG Path
- WEBP Path
ComfyUI's built-in Save Image writes a PNG with the whole workflow jammed inside it and calls it a day, which is the right default for most people. This node exists for the other case: the same image as a lossless PNG master, a shareable JPEG and a small WebP, with metadata you computed in the graph rather than the graph itself.
How it works
For each image in the batch it converts the tensor back to PIL, optionally bakes in a watermark, and saves a file per enabled format. Filenames are <filename>_00001.ext - five-digit zero-padded counter, appended automatically. Before saving it scans the destination for files matching that pattern and starts one past the highest, so repeated runs into the same folder keep counting instead of overwriting.
Then the metadata. Your Metadata string isn't written by PIL - it goes through a sanitiser, then the ime binary stamps it into the finished file via ime <file> --set @<tempfile>.
The sanitiser explains most of the surprises. ime only accepts two top-level keys - exif and custom - so anything else you pass gets moved, not rejected: for PNG your stray keys are wrapped into custom.PngText, for JPEG and WebP into custom.UserComment. It also translates between those two containers per target format, because a PNG text chunk and an EXIF UserComment are different homes for the same data. And if your metadata isn't a JSON object at all - a plain string, an A1111-style parameters block, a truncated paste - the sanitiser returns empty and the metadata is silently skipped. The image still saves, green run, nothing inside.
The inputs and outputs that matter
The toggles. save_png, save_jpg, save_webp all default to true - so out of the box you get three files per image. That's the trap in this node. If you wanted one, turn the other two off, or set Format Override to png / jpg / webp and let it ignore the toggles entirely (jpeg is accepted too). If you manage to turn all three off, it quietly falls back to PNG rather than saving nothing.
Quality. png_compress_level (0β9, default 4 - a sane speed/size middle), jpg_quality (default 95), webp_quality (default 95) and webp_lossless.
Where and what. filename is the base name, default HondaImage. path_override is a directory - not a file - and defaults to ComfyUI's output/. metadata is the JSON string. All three are forced inputs, so you wire them rather than type them, which is exactly what you want here: Path Join for the directory, Text Concatenate for the name, JSON Merge or JSON Set Key for the metadata.
Watermark, optional, takes the pack's HONDA_WATERMARK type - connect an Image Watermark or Text Watermark node.
Outputs: Saved Paths (an array of every file written), plus PNG Path, JPG Path, WEBP Path. The three single paths are the first file saved in each format, so a batch of eight gives you image one's paths plus the full list. Wire them into Move File, Rename File or Print to Console.
One consequence of the ime mechanism: the file contains only the metadata you passed in. ComfyUI's native Save Image embeds the workflow and prompt chunks that make a PNG drag-loadable; this node writes a fresh PIL image with no text chunks and adds your JSON. Hand someone that PNG and they get a picture, not a workflow. If you post to CivitAI and want model auto-linking, you build that metadata yourself - which is the whole reason this node's JSON siblings exist.
How to install it
In Avaray/honda-nodes - ComfyUI Manager β Node Pack β search Honda Nodes β Install β restart. Or:
cd ComfyUI/custom_nodes
git clone --depth 1 https://github.com/Avaray/honda-nodes.git
cd honda-nodes
python install.py
The installer is required here: it downloads ime (the author's image-metadata-editor, from its GitHub releases into the pack's bin/ folder) and jq. Without it the node still saves pixels, but every metadata injection is skipped with a console warning. Needs ComfyUI 0.38.0+ - it's V3-schema.
Common issues
Files saved, metadata missing. In order of likelihood: the metadata string wasn't valid JSON (validate it upstream with JSON Validate); ime isn't installed (look for Warning: 'ime' CLI not found); or the injection failed and printed a warning you scrolled past. The node never fails a save because of metadata, so the console is the only place this surfaces.
The counter jumped or overwrote something. The scan only recognises files named exactly the base name plus digits, so a hand-renamed file doesn't register and the next run can collide with it. Two workflows writing the same base name to one folder at once also collide: the counter is computed at the start of the save.
Your PNG won't drag back into ComfyUI. By design, as above - no workflow chunk. Keep the default Save Image in parallel if you rely on that.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| save_png | BOOLEAN | true | β |
| save_jpg | BOOLEAN | true | β |
| save_webp | BOOLEAN | true | β |
| png_compress_level | INT | 40β9 | 0=fastest/largest, 9=slowest/smallest. |
| jpg_quality | INT | 951β100 | β |
| webp_quality | INT | 951β100 | Only applies when WEBP Lossless is off. |
| webp_lossless | BOOLEAN | false | β |
| metadataopt | STRING | {} | JSON object with metadata to inject via 'ime'. |
| path_overrideopt | STRING | Absolute path to a directory. If empty, uses the default ComfyUI output directory. | |
| format_overrideopt | STRING | Provide 'png', 'jpg', or 'webp' to save ONLY in that format, ignoring the toggles in this node. | |
| filenameopt | STRING | HondaImage | Base filename. A counter will be appended automatically. |
| watermarkopt | HONDA_WATERMARK | Connect an 'Image Watermark' or 'Text Watermark' node. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| Saved Paths | ARRAY | β |
| PNG Path | STRING | β |
| JPG Path | STRING | β |
| WEBP Path | STRING | β |