Nodes/ComfyUI-FrameIO/Batch Save Image Sequence (WebP)
ComfyUI Node

Batch Save Image Sequence (WebP)

PNG frame dumps are eating your disk — save WebP instead

By room3dev·Created 8 months ago·Updated 7 months ago· 0
Batch Save Image Sequence (WebP)
  • images
  • paths
  • count
path_pattern./frame{:06d}.webp
start_index0
losslesstrue
quality95
skip_identicalfalse
overwritetrue

Long video renders have a dirty secret: the frame dump costs more disk than the model weights did. A 600-frame PNG sequence of 1080p frames is multiple gigabytes of mostly-redundant pixels, and once you start iterating on a shot, you're burning tens of gigabytes per take. This node is the fix. It takes whatever IMAGE batch you hand it - straight off a KSampler, a video-decoded sequence, whatever - and writes it out as a WebP frame sequence at a fraction of the size. The README claims 5–10× smaller than PNG, and honestly that's in the right ballpark for video frames.

Mechanically it's straightforward: each frame in the batch gets formatted into your path_pattern (default ./frame{:06d}.webp) starting at start_index, and saved with PIL. The interesting parts are the toggles:

  • lossless - default true. Lossless WebP still crushes PNG in size; flip it to false for lossy compression when you're iterating and don't care about archival quality.
  • quality - 1–100, default 95. Only used in lossy mode; in lossless mode quality is ignored entirely.
  • skip_identical - this is the node's party trick. Each frame is SHA-1 hashed, and if a frame matches one it's already seen, it's not re-saved - the returned path list just points at the earlier identical frame. Static shots collapse to a handful of files. Huge for talking-head and locked-camera videos.
  • overwrite - default true (re-writes every time). Set it to false for resumable renders: existing frames are left alone, and this is what makes partial re-renders safe.

Outputs are paths as a STRING_LIST and an INT count. That list is the whole point of the pack: the recommended flow is Save WebP → feed paths straight into the pack's Batch Load Image List node → IMAGE → your Video Combine / FFmpeg step. No filename guessing, no re-importing.

Where people get burned:

  • skip_identical returns duplicate path entries. If frames 40 and 41 are identical, the list contains the same path twice, and loading it back reproduces 600 frames with frame 41 being a re-show of frame 40. That's correct behavior (frame count preserved), but it means you shouldn't re-save with a naive count-based loader - use the list loader.
  • The path you type is the path you get back. The node returns your pattern string as written, not an absolute path. It does resolve to absolute internally for saving, but the output list carries what you typed.
  • Security restriction is real. The node only writes inside ComfyUI's output directory - it literally checks commonpath against the output folder and raises PermissionError otherwise. You can't use it to write frames to some random project folder. Annoying, but it's a deliberate guard, not a bug.
  • WebP still trips up downstream tools. Community threads about "WebP to MP4 after Wan2.1" are a genre. FFmpeg handles WebP fine, but some GUI video tools and old pipelines don't. If you're handing frames to something picky, render to PNG for the final pass - this node is for the iteration middle, not necessarily the deliverable.

Install: ComfyUI Manager → search "ComfyUI-FrameIO", or:

cd ComfyUI/custom_nodes
git clone https://github.com/room3dev/ComfyUI-FrameIO

Restart, find it under FrameIO. Dependencies are just pillow and numpy - no models, no ffmpeg bundled. For the recommended settings, the README is sensible: quality 95 with skip-identical on for final renders, quality 90 while iterating, lossless for datasets. Save it, load it back, and stop letting PNG hoard your SSD.

CategoryFrameIO

Inputs (7)

NameTypeDefaultDescription
imagesIMAGE
path_patternSTRING./frame{:06d}.webp
start_indexINT0
losslessCOMBOtrue2 options: false, true
qualityINT951–100
skip_identicalCOMBOfalse2 options: false, true
overwriteCOMBOtrue2 options: true, false

Outputs (2)

NameTypeDescription
pathsSTRING_LIST
countINT