ComfyUI Node

Save EXR

Where PNG quietly lies to you

By spacepxl·Created 3 years ago·Updated 6 months ago· 102
Save EXR
  • images
    filename_prefixComfyUI
    tonemapsRGB
    version1
    start_frame1001
    frame_pad4
    save_workflow
    create_path_if_missingfalse

    PNG is 8 bits per channel: 256 possible values for red, green, and blue. That's plenty for a photo you're going to post, and it's nowhere near enough for data masquerading as an image. A depth map, a displacement map, a normal pass, an HDR capture - these want floating-point values, and this node is how you get them out of ComfyUI. It writes 32-bit float EXR, RGB or RGBA, with version and frame numbering, overwrite protection, and (optionally) your workflow JSON saved alongside.

    People in the community use it exactly that way: when a Depth-Anything release dropped, the comment section turned into "how do I get this out at more than 8 bits," and the answer was these EXR nodes. The data survives; PNG was quietly quantizing it.

    How it works

    On the way to disk it reverses the tonemap you'd see on screen: sRGB-encoded values get converted back to linear, and if you picked Reinhard it applies the inverse compression. So the stored file is scene-linear float data, not a display encoding. It flips RGB→BGR for OpenCV and, if you're saving an alpha channel, inverts it - that's an OpenCV EXR convention, and it's the one quirk to remember if your alpha ever looks backwards.

    The output naming is the part you'll actually think about. With a relative filename_prefix it writes to ComfyUI's output folder using the standard counter scheme. With an absolute path it builds name_v###.NNNN.exr - version (default 1) gives you _v001, set it to -1 to drop the version entirely, and start_frame + frame_pad control the frame number, so start_frame 1001 with frame_pad 4 gives you .1001.exr. VFX pipelines start at 1001 for a reason; this node speaks that language.

    It also refuses to overwrite: if the target file already exists, it stops and raises. Rerun a workflow and you'll hit it - bump the version and move on.

    The inputs that matter

    • tonemap - linear stores raw values as-is; sRGB/Reinhard convert from display encoding to linear first. For most exports sRGB is right, because ComfyUI hands you sRGB-encoded images.
    • version / start_frame / frame_pad - the naming scheme above.
    • save_workflow - ui, api, ui + api, or none. Turns out EXR has no metadata slot for workflows (it's not PNG), so this writes _api.json and _ui.json files next to your image instead. Set it to ui if you ever want to drag a generation back into the graph later.
    • create_path_if_missing - only matters for absolute paths; lets it make the directory rather than erroring.

    Install

    Same pack as everything else: ComfyUI Manager → search ComfyUI-HQ-Image-Save → install → restart, or git clone https://github.com/spacepxl/ComfyUI-HQ-Image-Save into ComfyUI/custom_nodes/. Only imageio and opencv-python as dependencies, no models.

    The author's own tip

    For generation you intend to save as EXR, run ComfyUI with --fp32-vae. The VAE decode runs in fp16 by default, and if you're going to the trouble of storing full float precision, you don't want the last step before it dropping bits. The README says exactly this.

    CategoryHQ-Image-Save

    Inputs (8)

    NameTypeDefaultDescription
    imagesIMAGE
    filename_prefixSTRINGComfyUI
    tonemapCOMBOsRGB3 options: linear, sRGB, Reinhard
    versionINT1-1–999
    start_frameINT10010–99999999
    frame_padINT41–8
    save_workflowCOMBO4 options: ui, api, ui + api, none
    create_path_if_missingBOOLEANfalse

    Outputs (0)

    No outputs