Nodes/MTB Nodes/Save Gif (mtb)
ComfyUI Node Runs on cloud

Save Gif (mtb)

Turn an image batch into an animated GIF in ComfyUI

By melMass·Created 3 years ago·Updated about a month ago· 723
Save Gif (mtb)
  • image
    fps12
    resize_by1.00
    optimizefalse
    pingpongfalse
    resample_filter
    use_ffmpegfalse

    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 when resize_by isn't 1. lanczos for quality, nearest for 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.

    Categorymtb/IO

    Inputs (7)

    NameTypeDefaultDescription
    imageIMAGE
    fpsINT121–120
    resize_byFLOAT1.00
    optimizeBOOLEANfalse
    pingpongBOOLEANfalse
    resample_filterCOMBO6 options: nearest, box, bilinear, hamming, bicubic, lanczos
    use_ffmpegBOOLEANfalse

    Outputs (0)

    No outputs