Citron Image Saver Simple
One wire instead of twenty input sockets
- images
- metadata
- hashes
- a1111_params
The full Citron Image Saver is a great node with an ugly body: twenty-odd optional sockets, half of which you wire every single time. Citron Image Saver Simple is the same save engine with that whole block collapsed into a single metadata wire. You build the metadata elsewhere - with the pack's own Metadata node - and this node just saves.
Same writer, same output files, same parameters chunk and embedded workflow. The reason to reach for it is graph readability. If your working canvas has three savers (base pass, hires pass, upscale), wiring twelve inputs into each one is how a workflow turns into a spider. One METADATA fan-out, three copies of the saver, done.
How it works
This is a straight split of one class into two. Citron Image Saver Metadata does the expensive part: resolves your checkpoint name to a file, SHA-256s it, scrapes <lora:...> and embedding:... out of the prompt text and hashes those too, then formats the A1111 string. The result is passed along as a METADATA object. Simple takes that object and hands it to the shared save routine.
That means the required inputs here are only the file-shaping ones: images, filename, path, extension, plus the compression knobs lossless_webp, quality_jpeg_or_webp, optimize_png, embed_workflow and save_workflow_as_json. The optional ones are metadata, counter, time_format and show_preview. Filename templating works exactly as on the full saver - %time_%basemodelname_%seed by default, with %date, %model, %width, %height, %seed, %counter, %sampler_name, %steps, %cfg, %scheduler_name, %denoise, %clip_skip all available.
Outputs are hashes and a1111_params, same as the parent - chain hashes into another saver's additional_hashes if you're writing several derivatives of one generation.
The trap is the unconnected case. Leave metadata empty and the node doesn't complain; it saves with an empty metadata object and writes a parameters string full of defaults - unknown for both prompts, Steps: 20, an empty Sampler: field, no model. The image looks fine and the metadata is a lie. If a file from this node says "unknown" everywhere, that's what happened.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/citronlegacy/ComfyUI-CitronNodes
# restart ComfyUI
Manager search is hit-or-miss - the README lists Manager support as "coming soon" and the package metadata is still placeholder - so clone it. Only dependency is piexif, needed for writing the parameter string into JPEG/WebP EXIF:
pip install piexif
No models to download. You'll find both saver nodes and the Metadata node under Citron_ImageSaver.
Common issues
- Metadata chunk missing on a JPEG. EXIF has a hard 65535-byte ceiling; the node drops the embedded workflow first and skips metadata only if that's still not enough. PNG has no such limit.
- Everything says "unknown". Missing
metadatawire. Wire the Metadata node'smetadataoutput here. - A save hangs the first time on a new checkpoint. That's the SHA-256 pass, cached afterwards in a
.sha256file next to the model. One-time cost per model file. - LoRA hashes don't appear. The hashing only sees LoRAs named in the prompt strings you fed to the Metadata node - text tags, not loader nodes.
- The pack won't load at all. Missing
piexiffails the import for the entire pack, not just the savers.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | image(s) to save | |
| filename | STRING | %time_%basemodelname_%seed | filename (available variables: %date, %time, %model, %width, %height, %seed, %counter, %sampler_name, %steps, %cfg, %scheduler_name, %basemodelname, %denoise, %clip_skip) |
| path | STRING | path to save the images (under Comfy's save directory) | |
| extension | COMBO | file extension/type to save image as | |
| lossless_webp | BOOLEAN | true | if True, saved WEBP files will be lossless |
| quality_jpeg_or_webp | INT | 1001–100 | quality setting of JPEG/WEBP |
| optimize_png | BOOLEAN | false | if True, saved PNG files will be optimized (can reduce file size but is slower) |
| embed_workflow | BOOLEAN | true | if True, embeds the workflow in the saved image files. Stable for PNG, experimental for WEBP. JPEG experimental and only if metadata size is below 65535 bytes |
| save_workflow_as_json | BOOLEAN | false | if True, also saves the workflow as a separate JSON file |
| metadataopt | METADATA | metadata to embed in the image | |
| counteropt | INT | 00–18446744073709550000 | counter |
| time_formatopt | STRING | %Y-%m-%d-%H%M%S | timestamp format |
| show_previewopt | BOOLEAN | true | if True, displays saved images in the UI preview |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| hashes | STRING | Comma-separated list of the hashes to chain with other Image Saver additional_hashes |
| a1111_params | STRING | Written parameters to the image metadata |