Image Saver
Save your images with prompt + Civitai-ready metadata baked in
- images
- hashes
- a1111_params
ComfyUI's built-in Save Image node writes the workflow into the PNG and calls it a day. That's fine until you upload the result to Civitai and it can't figure out which model or LoRAs you used, so nothing gets linked and your generation shows up naked. Image Saver fixes exactly that. It writes the same A1111-style parameters string that Automatic1111 and Civitai's "geninfo" auto-detection expect - prompt, negative, steps, sampler, CFG, seed, size, model hash - plus the hashes of your model, LoRAs and embeddings so Civitai links every resource automatically.
If you post to Civitai at all, this is the node you actually want as your final save step.
How it works
The node takes your finished images and assembles a metadata block from everything you tell it about the run. For PNG it embeds two things: the full ComfyUI workflow (so the image is still draggable back into the editor) and the A1111 parameters string. For JPG and WEBP it writes just the A1111 params, since those formats don't carry the workflow graph. The clever part is hashing - it computes the hashes Civitai uses for resource matching, so an uploaded image resolves back to the exact checkpoint and LoRAs on the site. You can also drop LoRAs into the prompt as <lora:name:weight> and they'll be turned into hashes and stored too.
The catch, and it's the whole design of this pack: the node doesn't read your KSampler. You have to hand it the values. That's why the pack ships all those little literal and selector nodes - the idea is you define seed/steps/cfg/sampler once and wire each into both the KSampler and this node, so the saved metadata is guaranteed to match what actually ran.
The inputs and outputs that matter
- filename - supports placeholders like
%basemodelname,%seed,%time,%counter,%sampler_name. The default%time_%basemodelname_%seedis already a sane, sortable name. - path - subfolder under your ComfyUI
outputdir; also takes placeholders. - extension -
png,jpeg,jpgorwebp. PNG if you want the workflow embedded; WEBP if you want small files with params still readable. - modelname / positive / negative / steps / cfg / sampler_name / seed_value - the metadata fields. Feed these from the same nodes driving your sampler.
- additional_hashes - paste AutoV3 hashes from Civitai for stuff the node can't see (wildcards, ControlNets) so those get linked too.
Outputs are hashes and a1111_params, both strings - handy for piping into a text preview if you want to eyeball what got written.
Installing it
ComfyUI Manager: search ComfyUI Image Saver, install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/alexopus/ComfyUI-Image-Saver
cd ComfyUI-Image-Saver
pip install -r requirements.txt
Restart ComfyUI and hard-refresh. There's a small requirements.txt (used for metadata writing and the Civitai API lookups) but no model downloads and nothing heavy.
Where people get tripped up
The classic one: an error like bad operand type for abs(): 'str' on save. That's the clip_skip input receiving a string instead of a number - usually because it got converted to an input and wired to something text-y, or left empty. Set the clip_skip widget back to a plain integer (1 or 2) and it saves fine. It's a reported, real failure, not a rare fluke.
The other one is expecting Civitai to detect resources it never saw. If a LoRA isn't loaded through a node the saver can inspect, or you typed the model name by hand and the hash doesn't match a version on the site, nothing links. Use the loader-with-name nodes from this pack so the exact filename and hash flow through, and reach for additional_hashes for anything off-graph. And remember JPG/WEBP drop the workflow - keep PNG if being able to re-open the image in ComfyUI matters to you.
Inputs (28)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | image(s) to save | |
| filename | STRING | %time_%basemodelname_%seed | filename (available variables: %date, %time, %time_format<format>, %model, %width, %height, %seed, %counter, %counter<padding>, %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 | |
| stepsopt | INT | 200–10000 | number of steps |
| cfgopt | FLOAT | 7.000–100 | CFG value |
| modelnameopt | STRING | model name (can be multiple, separated by commas) | |
| sampler_nameopt | STRING | sampler name (as string) | |
| scheduler_nameopt | STRING | normal | scheduler name (as string) |
| positiveopt | STRING | unknown | positive prompt |
| negativeopt | STRING | unknown | negative prompt |
| seed_valueopt | INT | 00–18446744073709550000 | seed |
| widthopt | INT | 5120–16384 | image width |
| heightopt | INT | 5120–16384 | image height |
| lossless_webpopt | BOOLEAN | true | if True, saved WEBP files will be lossless |
| quality_jpeg_or_webpopt | INT | 1001–100 | quality setting of JPEG/WEBP |
| optimize_pngopt | BOOLEAN | false | if True, saved PNG files will be optimized (can reduce file size but is slower) |
| counteropt | INT | 00–18446744073709550000 | counter |
| denoiseopt | FLOAT | 1.000–1 | denoise value |
| clip_skipopt | INT | 0-24–24 | skip last CLIP layers (positive or negative value, 0 for no skip) |
| time_formatopt | STRING | %Y-%m-%d-%H%M%S | timestamp format |
| save_workflow_as_jsonopt | BOOLEAN | false | if True, also saves the workflow as a separate JSON file |
| embed_workflowopt | 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 |
| additional_hashesopt | STRING | hashes separated by commas, optionally with names. 'Name:HASH' (e.g., 'MyLoRA:FF735FF83F98') With download_civitai_data set to true, weights can be added as well. (e.g., 'HASH:Weight', 'Name:HASH:Weight') | |
| download_civitai_dataopt | BOOLEAN | true | Download and cache data from civitai.com to save correct metadata. Allows LoRA weights to be saved to the metadata. |
| easy_remixopt | BOOLEAN | true | Strip LoRAs and simplify 'embedding:path' from the prompt to make the Remix option on civitai.com more seamless. |
| show_previewopt | BOOLEAN | true | if True, displays saved images in the UI preview |
| customopt | STRING | custom string to add to the metadata, inserted into the a111 string between clip skip and model hash |
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 |