Nodes/ComfyWarp/SaveFrame
ComfyUI Node

SaveFrame

Write the stylized frame where RenderVideo can find it

By Sxela·Created 3 years ago·Updated 2 months ago· 49
SaveFrame
  • image
    output_dir
    batch_nameComfyWarp
    frame_number0

    Every frame your loop produces needs to land somewhere, and this is that somewhere. SaveFrame takes the current output image, writes it to a folder as a PNG named after the current frame number, and returns nothing - it's a terminal output node, the exit door of the diffusion loop. If you're building a ComfyWarp pipeline, this is where your stylized frames accumulate into the sequence that RenderVideo later turns into a movie.

    The naming is the part that has to line up, because it's a contract with the renderer. The file is written as {batch_name}_{frame_number:06}.png - so with the default batch_name of ComfyWarp at frame 42, you get ComfyWarp_000042.png. RenderVideo reads back {batch_name}_%06d.png from its own frames_input_dir. Keep the batch_name identical on both nodes and the pattern matches automatically; change one and the other finds nothing. This is the single most common wiring mistake in the pack, and it fails silently until the very end, when your video comes out empty.

    Inputs

    • image - the frame to save, usually the sampler's decoded output (after VAE decode).
    • output_dir - where to write. It's created if missing. Empty string writes into your ComfyUI working directory, which is rarely what you want - set it to a real folder.
    • batch_name (default ComfyWarp) - the name prefix, and the value that must match RenderVideo.
    • frame_number - the current position in the loop. Wire FixedQueue's current output here (or wherever your frame counter lives), not a fixed value, or every frame will overwrite the same file.

    It saves the first image in the batch (.cpu().numpy() of image[0]), so a batch of 1 is the normal case. Values are clamped to 0–1 and converted to uint8 before writing - no surprises there.

    Where it sits in the loop

    The canonical order: LoadFrameFromDataset (or the pair loader) → KSampler with the previous stylized+warped frame as init → VAE decode → SaveFrame with the counter → counter increments → repeat. Because MakeFrameDataset can be set to refresh on load, frames saved here also become visible to the loopback loaders, closing the circle. At the end, RenderVideo sees the same folder and encodes the whole thing. Get the folder and batch name right once, and this node quietly does its one job for the entire render.

    CategoryWarpFusion

    Inputs (4)

    NameTypeDefaultDescription
    imageIMAGE
    output_dirSTRING
    batch_nameSTRINGComfyWarp
    frame_numberINT00–9999999999

    Outputs (0)

    No outputs