Whisker: Sprite Sheet Generator
Turn a frame batch into a sprite sheet in one pass — background removal included
- frames
- image
- mask
You generated a short clip, and now the frames are a batch tensor and you need them as one sheet - for a game sprite, an animation contact sheet, or just to eyeball a whole video at a glance. That's this node's entire job: sprite_sheet takes an IMAGE batch (think VideoHelperSuite's Load Video, or an animated-WebP loader) and tiles the frames into a single grid_cols × grid_rows sheet. It's the "contact sheet" step that video workflows always seem to need and never want to wire by hand.
The optional extra is where it gets interesting. Because it lives in the same pack as the background-removal utilities, it can strip backgrounds while it assembles - handy when your animation frames have a solid backdrop you want gone before they become sprites.
How it works
Four stages, in order: prune, resize, remove background (optional), tile.
- Prune -
target_frame_countreduces the batch by step-skipping (everytotal // targetframes). This happens first, so a 120-frame clip becomes 16 frames before anything expensive runs. start_index/end_indexthen slice the pruned set --1forend_indexmeans "last frame", sostart_index=4, end_index=-1means "from the 5th kept frame onward."- Resize -
target_resolutioncaps the sheet's longest side; frames are resized first, so memory tracks the final output size instead of the raw clip resolution. Leave it at 0 to keep native frames. - Background removal - three modes:
none(all alpha opaque),per-frame(run BiRefNet or RMBG-2.0 on each kept frame), orwhole-sheet(assemble first, then one removal pass on the whole sheet).
The decision that matters: per-frame vs whole-sheet
This is the one choice that meaningfully changes the result. per-frame runs the model on each frame, which is slow but gives each sprite a clean, tight mask - and it's the only mode where padding_top/bottom/left/right do anything (each frame's subject is bbox-cropped, scaled to fit inside the cell minus padding, and centered). whole-sheet is one model pass, fast, but the model downsamples the assembled sheet to 1024 internally, so masks on a large sheet come out noticeably rougher. Rule of thumb: small sheets, whole-sheet; big sheets with detailed subjects, per-frame and eat the time.
Inputs and outputs
The schema is mostly obvious: frames in, grid_cols/grid_rows out. model (BiRefNet vs RMBG-2.0) matters only if you turn background removal on - and remember RMBG-2.0 is non-commercial without a paid license, so for shipping sprites stick with BiRefNet. Outputs are image (always 4-channel RGBA - the alpha is opaque in none mode) and mask (mirrors the sheet's alpha).
Two layout gotchas: if grid_cols × grid_rows exceeds the frame count, trailing cells are blank; if it's smaller, extra frames get dropped. Neither crashes, both surprise you the first time. And if a big sheet OOMs, target_resolution is the lever - it keeps the whole pipeline bounded.
Installing it
Shared pack install:
cd ComfyUI/custom_nodes
git clone https://github.com/nerdywhiskers/ComfyUI-Whisker-Nodes.git
pip install -r ComfyUI-Whisker-Nodes/requirements.txt
or search "ComfyUI-Whisker-Nodes" in ComfyUI Manager and restart. Under Add Node → whisker-nodes. First background-removal run downloads the model (~880MB) to your HuggingFace cache; if you never touch bg_removal, none of that ever happens.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| frames | IMAGE | — | |
| target_frame_count | INT | 161–1024 | — |
| start_index | INT | 00–1024 | — |
| end_index | INT | -1-1–1024 | — |
| grid_cols | INT | 41–64 | — |
| grid_rows | INT | 41–64 | — |
| target_resolution | INT | 00–16384 | — |
| bg_removal | COMBO | none | 3 options: none, per-frame, whole-sheet |
| model | COMBO | BiRefNet | 2 options: BiRefNet, RMBG-2.0 |
| padding_top | INT | 00–4096 | — |
| padding_bottom | INT | 00–4096 | — |
| padding_left | INT | 00–4096 | — |
| padding_right | INT | 00–4096 | — |
| position | COMBO | middle-center | 9 options: top-left, top-center, top-right, middle-left, middle-center, middle-right, +3 |
| crop_padding | INT | 00–4096 | Extra pixels kept around each frame's mask bbox before cropping, for breathing room. Same as BG Remove + Compose. |
| fit_to_canvas | BOOLEAN | false | Fit each cropped asset into the cell proportionally (allows upscaling). When off, the asset keeps its scale and is only reduced to fit. Same as BG Remove + Compose. |
| original_image_scale | FLOAT | 1.000.1–2 | Scale factor applied to each cropped asset. Ignored while fit to canvas is enabled. Same as BG Remove + Compose. |
| batch_size | INT | 41–128 | Frames per bg-removal forward pass. Only one chunk is on GPU at a time, so lower to 1-2 on small GPUs if per-frame bg removal runs out of memory. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |