Nodes/comfyui-lany-nodes/ImageSaverMini
ComfyUI Node

ImageSaverMini

The save node you swap in when you post to CivitAI

By lany42·Created 23 days ago·Updated 2 days ago· 1
ImageSaverMini
  • images
    ◄formatpng►
    ◄path►
    ◄filename%time_%model_%seed►
    ◄models►
    ◄positive—►
    ◄negative—►
    ◄seed0►
    ◄steps20►
    ◄width0►
    ◄height0►
    ◄time_format%Y-%m-%d-%H%M%S►
    ◄jpg_quality80►
    ◄optimize_pngfalse►
    ◄png_embed_workflowtrue►
    ◄additional_hashes►

    ComfyUI's built-in SaveImage writes your node graph into the PNG and calls it a day. That's great for reopening your own work and useless for a host that wants a flat A1111-style settings block to auto-link your checkpoint and LoRAs - which is why the replacement save node has been a genre for years (comfy-image-saver, then alexopus's ComfyUI-Image-Saver). Somebody posted the original complaint back in 2023: "it doesn't save appropriate generation metadata in images... That's a BIG let down" (15trfah). Four years on, the fix still takes a custom node.

    ImageSaverMini is that fix, and it's deliberately small: PNG or JPG, a filename template, and a metadata block with real hashes in it.

    What it does

    It's an output node with no outputs - you wire the final images in and that's the end of the graph. In one save it: expands its token template into a path and filename, hashes your model files, composes a generation-parameters string, attaches it plus (optionally) the workflow to the file, and writes the images. Save collisions get numbered suffixes (name.png, name_1.png) instead of overwriting.

    The metadata is the A1111 dialect, exactly as hosts expect it: positive prompt, a Negative prompt: line, then Steps:, Seed:, Size:, Model:, Model hash:, a Hashes: JSON object, Version: ComfyUI. Hashes are the first 10 hex characters of the file's SHA-256 - which is the Model-hash convention CivitAI matches on. Note what's not in there: there's no Sampler: or CFG scale: field in this string. Resources link fine; if you need the sampler recorded, that's not what this node writes.

    Where the metadata physically lands is format-dependent, and it's the mechanical heart of the thing. In PNG, the parameters block is written as a UTF-8 iTXt chunk so non-ASCII prompts survive - and if png_embed_workflow is on (it is by default), you also get the workflow and prompt chunks, meaning your image still reopens by drag-and-drop. In JPG there are no text chunks, so the same string goes into EXIF UserComment as UTF-16 with a BOM - there's a hard size cap on that field, and if your metadata overflows it the node tells you to use PNG instead. It's right: JPG is a derivative, PNG is the master.

    The inputs you'll actually set

    images is the only required image input. format picks png or jpg.

    path and filename are the two worth learning. Both expand tokens: %date, %time, %time_format<format>, %model, %seed, %steps, %width and %height. So path of %date/sdxl/png plus the default filename %time_%model_%seed gives you output/2026-09-28/sdxl/png/2026-09-28-143002_epicrealism_123456.png, with time_format (default %Y-%m-%d-%H%M%S) supplying the %time format. Absolute paths and ./.. are rejected, the result is confined to ComfyUI's output directory, and the expanded filename has to be ASCII letters, digits, underscores, hyphens and periods - no spaces.

    models is the comma-separated, models-directory-relative list - normally wired from ModelNames. First entry is the primary; the rest are hashed into the Hashes: block. positive and negative are socket-only, so you must wire your prompt text in; that's the point, since re-typing it is how prompts and images drift apart. seed, steps, width and height are metadata values you feed from the actual nodes - width/height accept 0 to mean "use the image's real dimensions". additional_hashes is for extra digests (a VAE, a component you've hashed yourself), comma-separated, no internal whitespace.

    Then the three options people skip: jpg_quality (ignored for PNG), optimize_png (smaller files, slower save), and png_embed_workflow (off = a smaller PNG that still has the parameters but no longer reopens as a workflow).

    Where it goes wrong

    The single most common failure is a model path the saver can't represent: spaces, parentheses, non-ASCII characters or a duplicated filename across folders. ModelNames raises on those before anything saves, and so does this node if you type the path yourself. Missing files are gentler - a wrong path just logs a warning and drops that hash, so your image still saves with Model hash: absent. That asymmetry surprises people: a typo costs you the hash, a legal-looking filename with a space costs you the run.

    Hashing large checkpoints costs real time the first save - the node reads the whole file - but results are cached per file (keyed on size, mtime and inode), so subsequent saves in the same session are instant. If your very first save stalls for a few seconds on a 12 GB model, that's this, not a hang.

    And one thing no saver can fix, which the corpus is clear about: hashes only auto-link resources that exist on the host. If your checkpoint isn't uploaded there, the metadata is accurate and nothing links.

    Install

    cd /path/to/ComfyUI/custom_nodes
    git clone https://github.com/lany42/comfyui-lany-nodes.git
    # restart ComfyUI
    

    Or search comfyui-lany-nodes in ComfyUI Manager ("ComfyUI Lany Nodes"). No models, no heavy dependencies - numpy and Pillow, both of which you already have. Python 3.13+ and a ComfyUI with the V3 node API; on an older build the pack doesn't register. Since this is an output node, remember to actually keep the PNG - the copy you upload to a host is a re-encoded derivative and loses the embedded workflow.

    CategoryLany Nodes

    Inputs (16)

    NameTypeDefaultDescription
    formatCOMBOpng2 options: png, jpg
    imagesIMAGE—
    pathSTRINGFolder inside ComfyUI's output directory. Leave empty to use the output directory. Supports %date, %time, %time_format<format>, %model, %seed, %steps, %width, and %height, as in filename. For example: %date/sdxl/png. No absolute paths or . or .. path components.
    filenameSTRING%time_%model_%seedFilename only; the extension is added automatically. Supports %date, %time, %time_format<format>, %model, %seed, %steps, %width, and %height. %model is the model filename without its extension. The result must use only ASCII letters, digits, underscores, hyphens, or periods, and cannot be '.' or '..'.
    modelsSTRINGComma-separated file paths under ComfyUI's models directory. Include extensions; the first file is the primary model. Filenames may use ASCII letters, digits, underscores, hyphens, or periods. No absolute paths or . or .. path components. Repeated paths are ignored; different files must have different filenames.
    positiveSTRING—
    negativeSTRING—
    seedINT00–18446744073709550000—
    stepsINT200–10000—
    widthINT00–9007199254740991Width stored in metadata. Set to 0 to use the image width.
    heightINT00–9007199254740991Height stored in metadata. Set to 0 to use the image height.
    time_formatSTRING%Y-%m-%d-%H%M%S—
    jpg_qualityINT801–100—
    optimize_pngBOOLEANfalseMake PNG files smaller without losing quality. May take longer to save.
    png_embed_workflowBOOLEANtrueSave the ComfyUI workflow and API prompt in PNGs. Generation metadata is always saved in PNG and JPG.
    additional_hashesSTRINGExtra metadata hashes, separated by commas. Surrounding whitespace and duplicates are ignored. No whitespace inside a hash.

    Outputs (0)

    No outputs