Nodes/ComfyUI-CitronNodes/Citron Image Saver Metadata
ComfyUI Node

Citron Image Saver Metadata

Build the parameters block once, save it anywhere

By citronlegacy·Created about a year ago·Updated 23 days ago· 0
Citron Image Saver Metadata
    • metadata
    • hashes
    • a1111_params
    ◄modelname►
    ◄positiveunknown►
    ◄negativeunknown►
    ◄width512►
    ◄height512►
    ◄seed_value0►
    ◄steps20►
    ◄cfg7.00►
    ◄sampler_name►
    ◄scheduler_namenormal►
    ◄denoise1.00►
    ◄clip_skip0►
    ◄additional_hashes►
    ◄custom►

    This is the least glamorous node in the pack and, if you save with Citron Image Saver Simple, the one you'll touch most. It assembles the generation metadata bundle: the prompts, the settings, the model name, and the hashes of every model file involved. No image goes in, no image comes out. It emits METADATA.

    Think of it as the difference between "write the caption in every file" and "write one caption, paste it into every file." Because the bundle is a single object on a wire, you can build it once from your sampler settings and your checkpoint loader, then feed the same bundle to three different savers - base, hires, upscale - and all three land with identical, correct parameters.

    How it works

    Its inputs are all optional, and that's deliberate: wire only what you have. modelname takes the model string (the pack's checkpoint and UNet loaders emit exactly this, filename included). positive and negative are the prompt strings. width, height, seed_value, steps, cfg, sampler_name, scheduler_name, denoise and clip_skip are the settings that end up in the A1111 line. additional_hashes takes Name:HASH pairs, comma-separated, for resources the resolver can't see. custom injects a free-text fragment between the CLIP-skip field and the model hash.

    The work happens in two passes. First, hashing: the model name is resolved against your checkpoints folder and then diffusion_models (.gguf allowed), SHA-256'd and truncated to ten characters. Your prompt strings get scanned for <lora:name:weight> and embedding:name tags, and each hit is resolved and hashed the same way. Second, formatting: it assembles the classic string -

    a photo of a cat
    Negative prompt: blurry, low quality
    Steps: 28, Sampler: dpmpp_2m, CFG scale: 4.5, Seed: 1234, Size: 1024x1024, Model hash: A1B2C3D4E5, Model: myModel, Hashes: {"LORA:x":...}, Version: ComfyUI
    

    Three outputs: metadata (the bundle for the Simple saver), hashes (a comma-separated Name:HASH string you can chain into another saver's additional_hashes), and a1111_params (the finished string). That last one is the debugging output - drop a Preview Text/show-text node on it and you can see exactly what will be written into the file before you commit a run.

    Note the multi-model trick: a comma-separated modelname treats the first entry as the primary and moves the rest into the hash list, which is how you get two checkpoints into one file's resource list.

    Install

    cd ComfyUI/custom_nodes
    git clone https://github.com/citronlegacy/ComfyUI-CitronNodes
    # restart ComfyUI
    

    Clone it manually rather than relying on Manager - the README still says Manager support is coming, and the repo metadata is placeholder. piexif is the pack's only pip dependency and it's needed by the saver, not this node, but a missing piexif breaks the pack's import as a whole, so install it:

    pip install piexif
    

    No model downloads.

    Common issues

    • Hashes are blank. The model name didn't match a real file. Names come back from loaders with their extension and any subfolder, and that exact string is what gets resolved.
    • LoRAs missing from Hashes:. They're found by regex over the prompt strings, not by watching your LoRA loader. If the tag isn't in the text you wired into positive, it isn't in the file.
    • First run stalls with a progress bar. SHA-256 over the checkpoint. It's cached in a .sha256 file beside the model, so it happens once per model file.
    • Everything reads "unknown". That's the default for positive/negative when you leave them unconnected. The string will still be written - it just won't be true.
    CategoryCitron_ImageSaver

    Inputs (14)

    NameTypeDefaultDescription
    modelnameoptSTRINGmodel name (can be multiple, separated by commas)
    positiveoptSTRINGunknownpositive prompt
    negativeoptSTRINGunknownnegative prompt
    widthoptINT5120–16384image width
    heightoptINT5120–16384image height
    seed_valueoptINT00–18446744073709550000seed
    stepsoptINT201–10000number of steps
    cfgoptFLOAT7.000–100CFG value
    sampler_nameoptSTRINGsampler name (as string)
    scheduler_nameoptSTRINGnormalscheduler name (as string)
    denoiseoptFLOAT1.000–1denoise value
    clip_skipoptINT0-24–24skip last CLIP layers (positive or negative value, 0 for no skip)
    additional_hashesoptSTRINGhashes separated by commas, optionally with names. 'Name:HASH' (e.g., 'MyLoRA:FF735FF83F98')
    customoptSTRINGcustom string to add to the metadata, inserted into the a111 string between clip skip and model hash

    Outputs (3)

    NameTypeDescription
    metadataMETADATAmetadata for Citron Image Saver Simple
    hashesSTRINGComma-separated list of the hashes to chain with other Image Saver additional_hashes
    a1111_paramsSTRINGWritten parameters to the image metadata