Nodes/ComfyUI-SaveImageWithMetaData/Save Image With Metadata
ComfyUI Node

Save Image With Metadata

Write A1111-style PNGInfo so CivitAI reads your images

By nkchocoai·Created 3 years ago·Updated about a year ago· 128
Save Image With Metadata
  • images
  • extra_metadata
    filename_prefixComfyUI
    sampler_selection_method
    sampler_selection_node_id0
    file_format
    lossless_webptrue
    quality100
    save_workflow_jsonfalse
    add_counter_to_filenametrue
    civitai_samplerfalse

    Here's the problem this node quietly solves. You generate a beautiful image in ComfyUI, upload it to CivitAI, and the site has no idea what model or LoRAs you used - no auto-detected resources, no clickable "made with" links, just your picture sitting there naked. Meanwhile the Automatic1111 crowd uploads and everything gets recognized instantly. Feels unfair. It kind of is.

    The reason is boring but important: ComfyUI does embed metadata in your PNGs - it stuffs the entire workflow JSON in there, which is how "drag the image back in and the graph rebuilds" works. But it does not write the flat, text-based PNGInfo block that A1111 pioneered - the one that reads Steps: 25, Sampler: DPM++ 2M, CFG scale: 7, Seed: ..., Model hash: ..., Hashes: {...}. That format is the lingua franca, and CivitAI parses it to identify your checkpoint and LoRAs by hash. ComfyUI never emits it, so your images arrive anonymous.

    Save Image With Metadata is a drop-in replacement for the stock Save Image node that writes that missing block. You wire your final image into it instead of the default saver, and it walks backwards through your graph to reconstruct the generation parameters, then bakes them into the file in the format everything else already understands.

    How it works - the clever part

    The node doesn't ask you to type in your settings. It finds your KSampler and reads the values straight off it and the nodes feeding into it: positive and negative prompt, steps, sampler, CFG, seed, model, the LoRAs and embeddings in the chain, VAE, plus the hashes CivitAI needs. Because it extracts these dynamically rather than from a hardcoded list, it also picks up values from many third-party sampler and loader nodes, not just the vanilla ones.

    The one wrinkle: which KSampler? If your workflow has several (hires fix, refiner passes), the node has to pick one to describe. That's what sampler_selection_method controls - Farthest grabs the KSampler furthest upstream (usually your base pass), Nearest grabs the closest one, and By node ID lets you name an exact node. For a plain single-sampler workflow, leave it alone; it only matters when you've got more than one.

    The inputs that actually matter

    Most of the ten-ish inputs you'll never touch. The ones worth knowing:

    • filename_prefix - the usual naming field, but it supports substitution keys. %seed%, %model%, %date%, %pprompt:20% (first 20 chars of the positive prompt) and friends get replaced with real values, so MyGen_%model%_%seed% becomes a filename you can actually search later.
    • file_format - png, jpeg, or webp. Keep it on png if you care about CivitAI; the flat PNGInfo lives in a PNG text chunk. JPEG/WebP metadata handling is flakier across tools. quality and lossless_webp only apply to the lossy formats.
    • civitai_sampler - off by default. Flip it on and the node translates ComfyUI's sampler names into the exact strings CivitAI expects, so your sampler shows up correctly instead of as garbage. If you're uploading there, turn this on.

    sampler_selection_node_id only does anything when method is By node ID. save_workflow_json optionally dumps a sidecar .json next to the image. add_counter_to_filename is the _00001 counter, on by default. And extra_metadata is an input socket that accepts the output of the Create Extra MetaData node from this same pack, for stamping in your own custom key/value fields.

    There are no outputs - this is a terminal save node, same as the stock one. It's the end of the line, not a pass-through.

    Installing it

    Via ComfyUI Manager (the easy way): open Manager, search ComfyUI-SaveImageWithMetaData, install, restart. Manager reads the pack, pulls it, and handles the deps - it's the same one-click path most people use now.

    Or by hand:

    cd ComfyUI/custom_nodes
    git clone https://github.com/nkchocoai/ComfyUI-SaveImageWithMetaData.git
    

    Then restart ComfyUI. No model downloads, no heavy dependencies, no CUDA anything - it's a pure-Python save node, so installs are quick and rarely break. The author (nkchocoai) ships a handful of small, focused ComfyUI utility packs; this is the one that gets around.

    Where people get tripped up

    • You still see anonymous uploads? Make sure you actually replaced the stock Save Image node with this one, and that your image path runs through it. Two save nodes side by side means only one file carries the metadata.
    • CivitAI shows the image but not the resources. Resources are matched by hash, and CivitAI can only link a model or LoRA it already knows. A private or unpublished LoRA won't resolve even though the hash is correctly embedded - that's CivitAI's side, not a bug here.
    • Wrong sampler pass described. Multi-KSampler workflow reading the refiner instead of the base? Switch sampler_selection_method to Farthest (or pin it with By node ID).
    • Metadata vanished after editing. Any tool that re-encodes the PNG - a resize, a compressor, some social platforms - strips the text chunks. Upload the original file the node produced, not a processed copy.
    CategorySaveImage

    Inputs (11)

    NameTypeDefaultDescription
    imagesIMAGE
    filename_prefixSTRINGComfyUI
    sampler_selection_methodCOMBO3 options: Farthest, Nearest, By node ID
    sampler_selection_node_idINT00–999999999
    file_formatCOMBO3 options: png, jpeg, webp
    lossless_webpoptBOOLEANtrue
    qualityoptINT1001–100
    save_workflow_jsonoptBOOLEANfalse
    add_counter_to_filenameoptBOOLEANtrue
    civitai_sampleroptBOOLEANfalse
    extra_metadataoptEXTRA_METADATA

    Outputs (0)

    No outputs