Image Frame Sample
Thin a long clip down to the frames that matter
- images
- images
Some batches are just too long to look at. A 300-frame video render, a folder of stills you want to skim, an animation you need to thumbnail for a contact sheet - nobody wants to scroll 300 previews to see if the shot held together. Image Frame Sample keeps a smaller set of frames from a batch, and the interesting part is the variety of ways it can pick them, because "which frames do you keep" is a real design question depending on what you're doing next.
It's from WAS Node Suite (WASasquatch's MIT pack, v3 ships 457 nodes), filed under WAS Suite/Animation, which tells you the audience: video and animation people doing frame bookkeeping.
The strategies
uniform(default) - evenly spaced frames across the range. Skim a 300-frame clip with 16 evenly spread looks at the motion arc.head,center,tail- the first, middle, or last consecutive run of frames. These are the ones anything temporal needs, because consecutive frames keep the motion intact. Need a few frames of the clip's opening for context, or its closing beat? Take a run.random- a seeded random pick, so a re-run keeps the same frames. Seed 0 is as good as any.every_nth- keep every nth frame (thenthinput, default 1). Classic stop-motion thinning: turn 120 frames at 24fps into every-2nd = 60.
The nth step actually applies to every strategy as a pre-thinning pass - set nth to 2 and head takes the opening of the clip on alternate frames, not the first ones. And num_frames caps what any strategy keeps, so uniform stops at 16 even on a 1000-frame batch.
The optional start / end inputs narrow the range the strategy picks from - start counts from 0, negatives count back from the end (−30 starts thirty frames before the end), and end is inclusive with −1 meaning the final frame. If an end lands before start, it's ignored and the whole sequence is used.
The one output
images - the frames that were kept, in their original order. That's it. It's a pure selection node: no resize, no duplication, no synthesis. Wire the result into a preview, a video saver, a contact-sheet builder, or another batch node.
When you'd reach for it
The honest answer is three jobs:
- Review. Uniform-sample a long render so you can actually watch the progression without a 5-minute encode.
- Context feeding. Video models and interpolation chains often want a short run of consecutive frames (the head or tail of a clip) rather than the whole thing - that's what
head/center/tailexist for, and what keeps a downstream temporal node from choking on 300 frames. - Thumbnails and keyframes.
uniformon a finished animation gives you the stills that best represent it;randomgives you an unbiased sample for a quick quality check.
The distinction that matters: if you need a continuous span (motion intact, temporal coherence), use head/center/tail. If you need representative coverage of the whole clip, use uniform or random. Feeding an interpolator with uniform-sampled, non-consecutive frames is how you get a stutter that looks like a bug.
Install
WAS Node Suite via ComfyUI Manager (search "WAS Node Suite v3") or git clone https://github.com/WASasquatch/was-node-suite-comfyui into ComfyUI/custom_nodes, then restart. Requires ComfyUI 0.14.0+ and Python 3.10+. v3 installs no Python packages and downloads nothing - a relief after v2's dependency-heavy installs.
One trap: num_frames silently caps at the batch's size, so asking for 16 from an 8-frame batch gives 8 - no error, no warning. If your sampled count looks wrong, check the input length first.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | The frames to sample, in order. | |
| num_frames | INT | 161–16384 | How many frames to keep, eg 16. Capped at what the batch holds, and every_nth stops here too. |
| strategy | COMBO | uniform | uniform = evenly spaced; head = first; center = middle; tail = last; random = a seeded pick; every_nth = every nth frame. head, center and tail are the consecutive ones anything temporal needs. |
| nth | INT | 11–16384 | Step between the frames the strategy may choose from. 1 uses every frame; 2 thins to every other one first, so `head` takes the opening of the clip on alternate frames. It applies to every strategy. |
| seed | INT | 00–18446744073709550000 | Seed for random, so a re-run keeps the same frames. Ignored by the other strategies. Any whole number; `0` is as good a seed as any. |
| startopt | INT | 0-16384–16384 | First frame to consider, counting from 0. Negative counts back from the end, so -30 starts thirty frames before it. The strategy picks from this range rather than from the whole sequence. |
| endopt | INT | -1-16384–16384 | Last frame to consider, inclusive. -1 is the final frame, which is the whole sequence together with a start of 0. An end before the start is ignored and the whole sequence is used. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | The frames that were kept, in order. |