Upload a file
  1. base64hub
  2. Image tools
  3. Base64 to GIF

Base64 to GIF

Paste the Base64 of a GIF and the animation plays right here. Download it as a .gif with all frames, timing and transparency intact.

Free no sign-up, no limits Local nothing uploaded Plays animation previewed before saving Updated Oct 27, 2026
Input –Output –Size –

Processed in your browser. This page cannot send your data anywhere – how we know

How to convert Base64 to GIF

  1. Paste the Base64 or a data:image/gif;base64,... URI into the box, or open a .txt file that contains it.
  2. Check that the status line says Detected GIF. The preview starts playing the animation, and the pixel size is listed above it.
  3. Press Download file to save it as .gif.

Nothing is redrawn or recompressed. The saved file has the same frames, delays, palette and transparency as the GIF that was encoded.

Is it really a GIF, and is it animated?

A GIF starts with GIF89a or GIF87a, which is R0lGODlh or R0lGODdh in Base64. Animation, transparency and loop control all need the newer 89a version, so a string starting R0lGODdh is in practice a still image.

Whether an 89a file moves depends on its content: one image block or many. The preview tells you at a glance. For a closer look, open Show hex dump. Animated GIFs usually carry the text NETSCAPE2.0 in the ASCII column; that is the block holding the loop count. With a small color table it sits in the first lines. A GIF with a full 256-color table has 768 bytes of palette first, which pushes the block past the 512 bytes the dump shows.

If the page says “This looks like WebP, not GIF” or names MP4, the “GIF” was converted on the way. Messaging apps and GIF search services often deliver animations as WebP or MP4 video because they are much smaller. Use Download as to save it under its real extension, or open it on Base64 to Video if it is an MP4.

Frames, timing and loops in code

To inspect a GIF without opening an editor, Pillow reads everything you need:

import base64, io
from PIL import Image

def gif_info(b64: str) -> dict:
    data = base64.b64decode(b64.split(",", 1)[-1])
    with Image.open(io.BytesIO(data)) as im:
        durations = []
        for i in range(getattr(im, "n_frames", 1)):
            im.seek(i)
            durations.append(im.info.get("duration", 0))
        return {
            "size": im.size,
            "frames": len(durations),
            "total_ms": sum(durations),
            "loop": im.info.get("loop"),
        }

For a 3-frame test animation with 100 ms per frame it returns {'size': (20, 20), 'frames': 3, 'total_ms': 300, 'loop': 0}. A loop of 0 means “repeat forever”; None means the file has no loop block and plays once. More on file handling in Base64 in Python.

Where Base64 GIFs come from

  • CSS and HTML loading spinners inlined as data:image/gif;base64,..., a habit from before CSS animations and SVG were common.
  • Old HTML email templates and signatures that embedded small animated logos.
  • API responses and chat exports that include stickers or reactions as Base64 fields.
  • Placeholder pixels: a 1×1 GIF used as an empty src. Its preview looks blank, so check the dimensions before assuming the decode failed.

GIF size after decoding

A GIF stores every frame with an old compression scheme, so short animations quickly reach megabytes, and Base64 adds a third on top. The Size row shows the decoded size: if a “small” GIF string is 5 MB, the GIF is about 3.75 MB. That is fine to decode here, but it is a poor candidate for inlining back into a page. If you are reworking it, a short MP4 or WebM loop is usually a fraction of the size. To encode a GIF, use GIF to Base64.

FAQ

Why does my decoded GIF play only once?

The loop setting is part of the file. Without a NETSCAPE2.0 block, or with a loop count of 1, browsers play the animation once and stop on the last frame. Decoding keeps whatever the file says; change it in a GIF editor.

How do I count the frames of a Base64 GIF?

The preview plays the GIF but does not count frames. In Python, Pillow’s n_frames gives the number, and the per-frame duration adds up to the total length; the snippet on this page does both.

Why does the GIF stop halfway or show a broken last frame?

The Base64 was cut off. Browsers play the frames that arrived and stop where the data ends. A complete GIF ends with the trailer byte 3B, so its Base64 usually ends in ADs=, Ow== or A7.