GIF to SVG: Trace a GIF in Its Own Palette

A GIF is an indexed image: one number per pixel, plus a table of up to 256 colours that is written into the file. This page reads that table, the frame count and the transparent index out of the bytes before it traces anything, so a 16-colour GIF comes back as an SVG with those same 16 fills — not sixteen colours chosen by a quantiser.

GIF87a / GIF89aExact paletteFrame count readNo upload

1. Drop a GIF

header parsed in this tab
Drop a .gif here
or
No image loaded yet — drop a GIF, or start from the sample.

2. Tracing

applies on change
Mode
Detail7
Smoothing6
Clean up
Decimalspath precision

3. Preview & export

—
Load a GIF to trace it
The fills below are copied from the GIF colour table; nothing is quantised in exact mode.

A GIF has no transparency in the alpha sense and no compression artefacts in the JPEG sense, but it does have something most converters ignore: a colour table written into the file. That table is the cheapest possible answer to the hardest part of tracing, which is deciding what the palette should be. Read it and the quantiser has nothing to do; ignore it and a sixteen-colour logo comes back as sixteen approximations of itself.

What is inside a GIF, block by block

The format is a header followed by a flat list of blocks, and each block is the reason for a quirk you may have met elsewhere:

BlockWhere it sitsWhat it decides
SignatureBytes 0–5GIF87a or GIF89a. Anything else is not a GIF, which is how a JPEG renamed to .gif gets caught
Logical screenBytes 6–12Canvas width and height, plus the packed byte that says whether a global colour table follows and how big it is (“size code N” means 2N+1 entries)
Global colour tableAfter the screen descriptorUp to 256 RGB triples. This is the palette the trace uses in exact mode
Graphic control extensionBefore each frameDelay, disposal method, and the one-bit transparent index — the closest a GIF gets to an alpha channel
Image descriptorOne per frameFrame rectangle, optional local colour table, interlace flag, then LZW data in sub-blocks
TrailerLast byte 0x3BEnd of file. Everything before it is frames, which is how the frame count is obtained without decoding any of them

Because the block list is self-describing, the frame count costs one pass over the file and no pixels at all. That is what the frames field above reports: it is the real count, read from the container, not a guess from the first extension block.

The palette is already the answer

Exact palette mode maps every pixel back to the table entry it came from and emits one <path> per entry actually used. On the sample below, a sixteen-entry table where five entries carry all the area, that produces five fills and no approximation at all. The swatches in the left panel are the table, largest area first, with pixel counts — useful because a GIF normally declares 256 entries and uses nine.

Reduction and threshold modes exist for the other two cases. Reduce re-quantises to 4, 8, 16 or 24 colours, which is what you want when the table holds two hundred near-identical greys from a scan. Black and white thresholds on luminance, and it is the mode that halves the path data on line art, because every anti-aliased edge stops being a separate band.

A GIF opened in the tool showing its version, frame count, colour table as swatches with pixel counts, and the traced SVG with the same five fills
The table is read from the file, so the swatches are the real entries and the trace fills reuse them: 6 fills, 13 rings, 146 nodes, 4.0 KB. · swipe to see it all

Dithering is what ruins a GIF trace

GIF has at most 256 colours, so anything with a gradient gets dithered: the encoder alternates two entries in a pattern so the eye averages them. To a contour tracer that pattern is real structure. Every dot becomes a closed ring of four pixels, the ring count explodes into the tens of thousands, and the SVG ends up several times larger than the GIF it came from while looking exactly as speckled as the original.

Two honest ways out. Trace the artwork before it was dithered — the PNG or the vector original. Or collapse the pattern here: switch to Reduce with four colours and let the 3×3 majority filter vote the checkerboard back into one flat fill. The second is a repair, not a recovery; the fine gradients are gone either way.

Transparency in a GIF is one bit

One index in the table is declared transparent, so a pixel is either fully visible or fully absent. There are no half values, which means edges in a GIF are hard or matted against whatever colour the file's author flattened them onto. This page keeps that index transparent, so a traced GIF of a logo on a transparent field produces an SVG with empty space around the mark — the same shape a cutter wants, with no white rectangle behind it.

If the file was flattened onto white instead, the transparent index is unused and you have an opaque white background. In that case trace normally and knock the white out afterwards with SVG Color Changer, or start from a cleaner source: a PNG to SVG conversion has a real alpha channel to work with.

Where a traced GIF is worth having

What it is not worth having: photographs, dithered gradients, and anything with soft shading. Those are pixel data pretending to be shapes, and a trace will faithfully reproduce the pretence.

Next steps

The export is a plain SVG with no embedded bitmap: shrink it with SVG Compressor, trim it with SVG Crop, Flip & Rotate, or check the namespace and viewBox with SVG Validator. Neighbouring formats have their own pages because their containers differ: WebP to SVG for the alpha plane and lossy prediction noise, and ICO to SVG for icon containers with several sizes inside.

Frequently asked questions

Why does the tool show the GIF's palette instead of its pixels?

Because the browser throws the palette away. A GIF stores one index per pixel plus a table of RGB triples; a canvas returns 24 bit colour with no record of the index. This page reads the table from the bytes, so a 16 colour GIF traces to exactly those 16 fills.

What happens to the animation?

The container is walked from header to trailer, so the frame count is real, and the first frame is traced. An SVG has no timeline. For a later frame, export that frame as PNG from an editor and trace the PNG.

Why does a dithered GIF trace badly?

Dithering replaces a flat area with a checkerboard of two entries, and a tracer cannot tell a deliberate pattern from noise: every dot becomes its own ring. Use Reduce with four colours so the majority filter collapses the pattern, or trace the original artwork.

Is GIF transparency the same as PNG transparency?

No. One palette index is reserved as transparent, so it is one bit: fully transparent or fully opaque. Anti-aliased edges cannot exist in a GIF, which is why traced GIF edges are hard.

Is the GIF uploaded?

No. The bytes are read with FileReader, the blocks are parsed in the tab and the frame is painted onto a canvas there. No upload endpoint, no external script.

Related SVG workflows

More free SVG tools