MP4 to GIF
Turn a short video into an animated GIF in this tab. Trim the part you want, pick the width, the frame rate and the number of colours. The browser decodes the video, retimes it and writes the GIF itself, so the file never leaves your computer.
Drop a video here
or choose a file · MP4, MOV, M4V, WebM · one at a time · up to 200 MB and 10 seconds of output · or paste with Ctrl + V
One video at a time · up to 10 seconds and 200 frames of output · 256 colours per frame · no upload · no account · no watermark
MP4 to GIF: What the Conversion Keeps, and What It Costs
Four seconds of video became 48 separate pictures. That is the whole trick, and it is also the bill: a 129.6 KB MP4 turned into a 4.62 MB GIF, because every one of those 48 frames is stored whole, at up to 256 colours, with no memory of the frame before it.
The numbers below come from this tool, run on four test clips at 480 × 270 and 12 fps. They explain why some videos convert cleanly and others explode in size.
How to turn an MP4 into a GIF here
- Add the video. Drop an MP4, MOV, M4V or WebM file into the box above, or paste one with Ctrl + V. One file at a time, up to 200 MB.
- Trim it. Start and End are in seconds. The output can be up to 10 seconds long; the hint under the fields shows the frame count before you commit.
- Set the size and rate. Width goes from 120 px to 960 px, but never wider than the source. Frame rate offers 6, 8, 10, 12, 15 and 20 fps; Colours offers 256, 128, 64 or 32.
- Download. The result card shows the pixel size, frame count, duration and file size. The preview is the GIF itself, so it loops at the rate the file will play.
Every change re-encodes on its own. There is no Run button: move a control, wait for the progress bar, look at the new size.
What each control does. Width sets the output pixels; height follows the source aspect ratio, rounded to an even number. Frame rate decides how many frames are sampled and how long each one is shown. Colours is the size of each frame's palette, from 256 down to 32; fewer colours make a smaller file and flatter gradients. Dither mixes neighbouring palette colours to hide banding, which looks smoother on gradients and adds noise, and bytes, on photos. Loop forever writes the Netscape loop block; switch it off and the GIF plays once.
A GIF is 48 pictures, not one movie
An MP4 stores a keyframe and then describes how later frames differ from it. A GIF has no such prediction. Each frame is a complete image with its own palette, and a decoder draws them one after another. Some GIF encoders fake inter-frame compression with transparent pixels that leave the previous frame showing, but the format itself has no way to say "same as before".
So the file size follows one number: what a single frame costs.
| Clip, 4 s at 480 × 270 | MP4 in | GIF out | Per frame | Growth |
|---|---|---|---|---|
| Motion test pattern | 169.6 KB | 931 KB | 19.9 KB | ×5.5 |
| Panning photo | 129.6 KB | 4.62 MB | 100.9 KB | ×36 |
| Screen recording | 8.5 KB | 375 KB | 8.0 KB | ×44 |
| Colour gradient | 11.3 KB | 687 KB | 14.6 KB | ×61 |
The two extremes are the useful ones. The screen recording is flat colour and text, so LZW compression finds long repeats in the flat areas: 8,003 bytes per frame, 375 KB for the clip. The panning photo has fine texture in every direction, and each frame averages 100,868 bytes. Multiply by 48 and the GIF is 4.62 MB.
That is also why the growth ratio is not a codec contest. The MP4 of a nearly static screen is unusually small (8.5 KB) because almost nothing changes between frames. The GIF cannot use that fact. Its 375 KB is 44 times larger, even though each individual frame compresses well.
What 256 colours actually cost
The photo frame holds 32,651 distinct colours. The GIF palette has 256 slots, and every frame in this tool carries its own 768-byte palette: 36,864 bytes across 48 frames, or 0.8% of the 4.62 MB file. The rest is pixel data.
Against the exact pixels the browser drew, at 256 colours and with dither on, the mean PSNR of the GIF was 34.6 dB on the photo, 40.5 dB on the screen recording and 49.6 dB on the gradient. The photo is the hard case because its texture changes on every frame.
Dither is a real trade, measured on the same frames:
| Clip | Dither off | Dither on | Size, off → on |
|---|---|---|---|
| Colour gradient | 44.4 dB | 49.6 dB | 374 KB → 687 KB |
| Panning photo | 36.2 dB | 34.6 dB | 4.02 MB → 4.62 MB |
On a synthetic gradient, dither removes visible bands and gains 5.2 dB. On a photo it adds fine noise: PSNR drops 1.6 dB while the file grows 15%, even though the result can look smoother to the eye. If size matters more than banding, turn Dither off.
Shared palettes are the other lever. At 64 colours and no dither, the photo GIF falls to 2.69 MB; the motion clip at 64 colours falls from 931 KB to 434 KB, a 53% cut.
The clock moves in hundredths of a second
GIF stores each frame's delay as a whole number of hundredths of a second. Twelve frames per second is 8.33 hundredths, which cannot be written exactly. This tool writes 8, 9, 8 and repeats: the first twelve delays in the 4-second motion GIF are 8, 9, 8, 8, 9, 8, 8, 9, 8, 8, 9, 8, and all 48 sum to exactly 400 hundredths, or 4.00 s. At 15 fps the same clip becomes 60 frames with 7, 6, 7 repeating, again summing to 4.00 s.
That is why the frame rate menu stops at 20 fps rather than offering 24 or 30. Above 20 fps the rounding error between requested and stored timing grows faster than the smoothness gained, and the frame count, hence the file size, grows linearly anyway. A 30 fps phone video is resampled to the rate you pick, not copied frame for frame.
Which dial buys the most
Same motion clip, three changes, measured:
| Change | Result | Effect |
|---|---|---|
| 480 px → 240 px at 15 fps | 1.14 MB → 413.5 KB | −64%, same 60 frames |
| 12 fps → 15 fps at 480 px | 931 KB → 1.14 MB | +22%, 48 → 60 frames |
| 256 → 64 colours at 12 fps | 931 KB → 434 KB | −53% |
Width is the strongest lever because pixels scale with its square: halving the width leaves a quarter of the pixels to encode. Frame rate is linear: a quarter more frames, a quarter more data. Colours change how well LZW can compress each frame, so the saving depends on the image; on this test pattern, dropping to 64 colours removed more than half the bytes.
A practical order for a GIF that has to fit a size limit: cut the width first, then the frame rate, then the colours, and leave dither on only if banding is visible.
What survives, and what does not
Audio is dropped. GIF has no sound channel. Nothing to configure, nothing to lose silently.
Colour follows the browser's decoder. The canvas holds 8-bit RGB, and the GIF keeps what the canvas held. On a full-range (pc) H.264 test clip, Chrome's canvas drew frames about 7 code values brighter than ffmpeg's decode of the same file; the GIF inherited that. The palette step is faithful to the browser, not to a separate reference decoder.
Frame timing becomes constant. A variable-frame-rate source is sampled at fixed intervals, so the GIF plays at one rate throughout.
More than 8 bits per channel is reduced before the palette. The canvas is 8-bit per channel, so a 10-bit source is already at 8 bits by the time a palette is chosen.
Rotation is applied before capture. The browser draws the video upright, and the canvas receives the rotated frame; portrait phone clips come out portrait.
Size and duration are capped. One file at a time, up to 200 MB, with at most 10 seconds and 200 frames of output. Those caps are deliberate. The four samples on this page ran about six seconds each for 4 seconds of video, so a 30-second clip would be minutes of work in an open tab.
Why the file never leaves the tab
The video is opened as a local object URL, decoded by the browser's own video element, drawn to a canvas and encoded by the page's JavaScript. There is no server step and no upload endpoint in the code.
You can check that without trusting the page. Open DevTools, switch to the Network panel, clear it, then change a setting. During the encode you will see no media or fetch request carrying your file; the only traffic is the page's own assets, already loaded.
The stronger test is to disconnect the network after the page loads. Loading a clip, trimming it and encoding it still work, because every byte is read from disk by the browser. In the offline run used for this page, a 3-second clip produced 30 frames and a 2.89 MB GIF with the network cut.
Encoding runs in the tab, so speed depends on the machine. On the desktop used for these tests, 48 frames at 480 × 270 took about six seconds; a phone will take longer, and a 10-second clip proportionally more.
Quick answers
Why is my GIF bigger than the MP4? Because the GIF stores every frame whole. A 4-second 480 × 270 photo clip went from 129.6 KB to 4.62 MB here; a flat screen recording went from 8.5 KB to 375 KB. The ratio varies with detail, but the direction does not.
How do I make the GIF smaller? Lower the width first. 480 to 240 px at 15 fps cut 1.14 MB to 413.5 KB on the motion clip. Then lower the frame rate or the colours, and turn Dither off if the image does not band badly.
What frame rate should I choose? 10 to 15 fps suits UI clips and short reactions. 12 fps is stored as 8, 9 and 8 hundredths per frame, which averages exactly 12. Higher rates add frames and bytes without making the motion much smoother.
Can I convert a 4K or vertical phone video? Yes, but the output width is capped at 960 px and never exceeds the source. A portrait clip keeps its orientation and its aspect ratio; height follows the width you choose.
Can I convert several videos at once? No. One file per run here. For batches, ffmpeg does the same job with a two-pass palette:
ffmpeg -i input.mp4 -vf "fps=12,scale=480:-1:flags=lanczos,split[a][b];[a]palettegen=stats_mode=full[p];[b][p]paletteuse=dither=sierra2_4a" output.gif
Is my video uploaded? No. The page has no server component for the conversion: the browser decodes the file and the page writes the GIF. You can confirm it by watching the Network panel or by converting with the network disconnected.