ComfyUI Node

Save Image

Save Image — Filenames That Actually Tell You What Made the Picture

By 0xBeycan·Created 24 days ago·Updated 4 days ago· 2
Save Image
  • images
    ◄filename_prefixComfyUI►
    ◄filename_keyssampler_name, cfg, steps, %F %H-%M-%S►
    ◄foldername_prefix►
    ◄foldername_keysckpt_name►
    ◄delimiter-►
    ◄save_job_datadisabled►
    ◄job_data_per_imagefalse►
    ◄job_custom_text►
    ◄save_metadatatrue►
    ◄counter_digits4►
    ◄counter_positionlast►
    ◄one_counter_per_foldertrue►
    ◄image_previewtrue►
    ◄output_ext.webp►
    ◄quality90►
    ◄named_keysfalse►
    ◄positive_text_opt—►
    ◄negative_text_opt—►

    The naming is the feature

    Six months in, your output/ folder is 4,000 files called ComfyUI_00001_.webp and the only way to tell them apart is to open them. The metadata is in there, but you can't see metadata in a file browser.

    This node builds folder and file names out of values pulled from your own graph - sampler_name, cfg, steps, the checkpoint, the resolution, the timestamp - so the filename is a summary of how the image was made. Wire it where your SaveImage goes and nothing else in the workflow changes.

    How the naming works

    filename_prefix is the fixed start. filename_keys is a comma-separated list appended in order, and each key is one of:

    • Any widget name from any node - sampler_name, cfg, steps, scheduler, denoise, ckpt_name, vae_name. When several nodes have the same widget, the highest-numbered node wins.
    • 13.cfg - that widget on node 13 specifically, when "highest-numbered wins" picks the wrong one.
    • resolution - the first image's WxH.
    • %F %H-%M-%S - any strftime format; the default keys end on a timestamp.
    • 'text' - a fixed literal, quotes kept.
    • /sub, ./sub, ../sub - step into a subfolder before the next key. A bare / is a separator.

    foldername_prefix and foldername_keys do the same thing for the subfolder under output/, and delimiter is the one character (default -) between parts. named_keys changes the format from 0001-seed-123456-cfg-5.0 to seed=123456-cfg=5.0, which reads better and parses worse. Model names lose their .safetensors extension, floats are trimmed, and Windows-hostile characters get dropped.

    The counter behaves the way you'd hope: it continues from the highest number already in that folder, counter_digits sets its width, and counter_position puts it before or after the name.

    The inputs that matter, and what comes out

    Beyond images (the only required input), there are two optional text sockets: positive_text_opt and negative_text_opt. They don't affect the image or the filename - they're saved into the job data and nothing else.

    There are no outputs at all. It's an output node, like the stock SaveImage, so it always runs and the cache works backward from it.

    output_ext defaults to .webp and covers .png, .jpg, .jpeg, .tiff, .bmp, .gif, .jp2/.j2k, plus .avif and .jxl when their Pillow plugins are installed. quality is that encoder's quality, and it has a wrinkle: 100 is lossless for WebP/AVIF/JXL, but for PNG it maps to compression level 0–9 - so on PNG it's a file-size dial, not a fidelity dial.

    save_metadata (on by default) embeds the prompt and workflow - PNG text chunks for PNG, EXIF Make and ImageDescription for everything else except BMP, which has neither.

    save_job_data appends an entry per run to a jobs.json in the folder, or one <image>.json per image with job_data_per_image on. The five levels add prompt texts, basic data, sampler settings and loaded models; job_custom_text is free text you can shove in.

    image_preview only decides whether the files appear in the queue/history gallery. Nothing is ever drawn under the node, so the node keeps whatever size you gave it - a small mercy when you have four of them stacked.

    Install

    Manager: search ComfyUI-BCNodes, install, restart. Manual:

    cd ComfyUI/custom_nodes
    git clone https://github.com/0xBeycan/ComfyUI-BCNodes
    

    The pack's requirements.txt (postfx, caption-audit) is only for the PostFx and Caption Audit nodes; this node needs nothing extra. Find it by typing BCNodes in the node library.

    Where people get burned

    The default extension is WebP, and WebP is not a master. WebP is smaller and it can carry a flat parameter string, but it is not the only format that round-trips back into ComfyUI - the README says ComfyUI loads PNG and WebP back into the editor, which is better than JPEG manages. Still, if this folder is your archive, set output_ext to .png. Keep the lossless file, publish the small one; the same rule the whole ecosystem runs on.

    If you want CivitAI to auto-link your models on upload, this node doesn't do that job either. It embeds ComfyUI's prompt and workflow; it does not write the flat A1111-style parameters block that CivitAI's auto-detection keys on. Same caveat the stock node carries. Nothing wrong with the node - just don't expect the swap to fix model linking.

    counter_digits: 0 overwrites. That setting writes a fixed name with no counter, so the next run silently replaces the previous file. Convenient for a "latest" file, a data-loss machine everywhere else.

    one_counter_per_folder does nothing. The tooltip says "Unused" and the README agrees - it survives only to keep the widget order stable across versions. Leave it alone.

    One honest limitation: filename_keys resolves against widget values, so a value that only exists at runtime (something computed mid-graph) isn't available to it. Widgets are.

    CategoryBCNodes/image

    Inputs (19)

    NameTypeDefaultDescription
    imagesIMAGE—
    filename_prefixSTRINGComfyUIFixed string the file name starts with
    filename_keysSTRINGsampler_name, cfg, steps, %F %H-%M-%SComma separated keys appended to the file name, in this order. Any widget name of any node works (`sampler_name, scheduler, cfg, denoise`, `ckpt_name`, `vae_name`, `model_name`); `13.cfg` picks node 13; `resolution` is WxH; `%F %H-%M-%S` is a strftime format; `'text'` is a fixed string; `/sub` starts a subfolder.
    foldername_prefixSTRINGFixed string the subfolder name starts with
    foldername_keysSTRINGckpt_nameSame rules as filename_keys; `/` or `../` make nested subfolders
    delimiterSTRING-One character placed between the parts; `/` makes subfolders
    save_job_dataCOMBOdisabledAppend an entry per job to jobs.json in the subfolder: prompt texts, basic data, sampler settings, loaded models
    job_data_per_imageBOOLEANfalseOne <image>.json per image instead of jobs.json
    job_custom_textSTRINGFree text saved with the job data
    save_metadataBOOLEANtrueEmbed prompt and workflow in the image (PNG text chunks, EXIF for the other formats)
    counter_digitsINT40–8Digits of the image counter: 3 gives image_001.png. Continues from the highest counter in the subfolder; 0 disables it
    counter_positionCOMBOlastimage_001.png or 001_image.png
    one_counter_per_folderBOOLEANtrueUnused
    image_previewBOOLEANtrueList the saved images in the queue / history gallery. They are never drawn under the node
    output_extCOMBO.webpFile format; AVIF and JXL appear when their Pillow plugins are installed
    qualityINT900–100Encoder quality for JPEG / JXL / WebP / AVIF / JPEG 2000 (100 = lossless for WebP / AVIF / JXL); PNG maps it to compression level 0-9
    named_keysBOOLEANfalsePrefix each value with its key: prefix-seed=123456-cfg=5.0-0001.webp
    positive_text_optoptSTRINGSaved as positive_prompt in the job data
    negative_text_optoptSTRINGSaved as negative_prompt in the job data

    Outputs (0)

    No outputs