Save Gif (mtb)
Turn an image batch into an animated GIF in ComfyUI
- image
You've got a batch of frames - from AnimateDiff, a video model, a batch-transform loop, whatever - and you want the classic looping GIF to drop in a Discord or a README. Save Gif (mtb) is the node that takes that image batch and writes the animated GIF. Simple job, and it does it without dragging in a video encoder unless you ask for one.
A ComfyUI "image batch" is just N frames stacked in one tensor, which is how every animation workflow represents its output before it gets saved. This node reads that batch in order and encodes it as a GIF at the frame rate you set. If you're coming from the video side of ComfyUI you'll usually reach for VideoHelperSuite's combine node for MP4s - Save Gif is the lighter option when you specifically want a GIF and want it now.
It's part of MTB Nodes (comfy_mtb) by melMass, a big grab-bag utility pack. The IO corner is where its save/load helpers live.
How it works
It walks the batch frame by frame and builds a GIF, using the classic PIL image pipeline by default. GIF is a palette format - 256 colors max per frame - so there's an optimize pass that trims the palette to keep file size sane, and a resample_filter that controls how frames get scaled if you shrink them. If you'd rather use a real encoder, use_ffmpeg hands the job to ffmpeg instead.
The inputs and outputs that matter
image- the batch of frames. This is the whole point; a single image just makes a one-frame GIF.fps(default 12) - playback speed. 12 is a sane default for AnimateDiff-length clips; bump it for smoother motion, drop it for a slideshow feel.pingpong(default off) - the boomerang toggle. Plays the frames forward then backward so the loop is seamless even when the last frame doesn't match the first. Genuinely useful for short loops that would otherwise "jump."resize_by(default 1) - scale factor. Set 0.5 to halve the dimensions and shrink the file.optimize(default off) - trims the color palette to reduce size. Worth turning on for anything you're uploading.resample_filter- the scaling filter (nearest, box, bilinear, hamming, bicubic, lanczos) used whenresize_byisn't 1.lanczosfor quality,nearestfor crisp pixel art.use_ffmpeg(default off) - encode via ffmpeg instead of PIL. Only relevant if you have ffmpeg installed and want its palette handling.
This is an output node - it writes the file to your ComfyUI output folder and previews it, so it doesn't hand a value onward. It's the end of the wire.
How to install it
ComfyUI Manager: search MTB Nodes, install, restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/melMass/comfy_mtb
then restart. The default PIL path needs nothing extra. If you plan to flip use_ffmpeg on, you'll want ffmpeg installed and on your PATH - otherwise leave that toggle off and PIL handles it.
Common issues & troubleshooting
The GIF looks banded or dithered. That's GIF being GIF - 256 colors is a hard limit, and gradients suffer. Turning optimize on can make it slightly worse in exchange for size. If color fidelity matters more than the format, save an MP4/WebM with a video node instead of a GIF.
The loop jumps. If the last frame doesn't line up with the first, the loop stutters. Turn on pingpong for a seamless boomerang, or generate frames that actually cycle back.
use_ffmpeg errors out. That path needs ffmpeg installed and reachable. If it's not, you'll get an encoder error - switch the toggle back off and the built-in PIL path will just work.
Huge file size. Long batch + full resolution = a fat GIF fast. Drop resize_by to 0.5, turn on optimize, and cut the frame count before you complain about the megabytes.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| fps | INT | 121–120 | — |
| resize_by | FLOAT | 1.00 | — |
| optimize | BOOLEAN | false | — |
| pingpong | BOOLEAN | false | — |
| resample_filter | COMBO | 6 options: nearest, box, bilinear, hamming, bicubic, lanczos | |
| use_ffmpeg | BOOLEAN | false | — |
Outputs (0)
No outputs