GIF (Graphics Interchange Format)
| Full name | Graphics Interchange Format |
|---|---|
| Extensions | .gif |
| MIME type | image/gif |
| Type | raster image, palette (up to 256 colors per frame), lossless LZW compression, animation |
| Starts with | 47 49 46 38 39 61 (GIF89a) or 47 49 46 38 37 61 (GIF87a) |
| Specification | GIF89a (W3C copy) |
| Maintained by | CompuServe (defunct); the format has been frozen since 1990 |
| License | open; the LZW patents expired in 2003-2004 |
GIF stores images with a palette of at most 256 colors and compresses them losslessly with LZW. Its lasting use is animation: a GIF can hold many frames with delays and loop forever, and it plays everywhere: browsers, chat apps, email clients and social networks. Single transparent color, no partial transparency.
For still images PNG is better (more colors, smaller files, real alpha). For animations, MP4/WebM video, animated WebP or AVIF are 5-10 times smaller at better quality, which is why sites like Giphy and Twitter convert uploaded GIFs to video. GIF stays popular because it works without a video player.
When to use GIF#
- Use for short, small animations that must play anywhere without a video player: reactions, UI demos in READMEs and docs, email.
- Use for simple graphics with few colors when you need compatibility with very old software.
- Avoid for photos: 256 colors give banding and dithering noise.
- Avoid for still graphics: PNG is lossless too, smaller and supports 8-bit alpha.
- Avoid for long or large animations: use MP4/WebM video, animated WebP or AVIF, which are much smaller.
File structure#
A GIF file is a header, a logical screen descriptor and an optional global color table, followed by a sequence of blocks and a trailer byte. All multi-byte numbers are little-endian.
47 49 46 38 39 61 "GIF89a"
0A 00 0A 00 logical screen: width 10, height 10
F7 packed: global color table, color resolution 8 bits, table size 2^(7+1) = 256
00 background color index
00 pixel aspect ratio (0 = none)
.. .. .. global color table: 256 x 3 bytes (R, G, B)
21 FF 0B application extension, 11 bytes follow
4E 45 54 53 43 41 50 45 32 2E 30 "NETSCAPE2.0"
03 01 00 00 00 sub-block: loop count 0 (forever), terminator
21 F9 04 graphic control extension, 4 bytes
04 0A 00 00 00 disposal 1 (keep), delay 10 (0.10 s), no transparency, terminator
2C image descriptor
00 00 00 00 0A 00 0A 00 left 0, top 0, width 10, height 10
00 packed: no local color table, not interlaced
08 LZW minimum code size
16 .. .. 00 image data in sub-blocks (length byte + data), 0 terminates
... more graphic control extensions + images = frames
3B trailer
Header and logical screen descriptor#
| Offset | Size | Field |
|---|---|---|
| 0 | 6 | signature and version: GIF87a or GIF89a |
| 6 | 2 | logical screen width (canvas) |
| 8 | 2 | logical screen height |
| 10 | 1 | packed: bit 7 global color table flag, bits 6-4 color resolution, bit 3 sort flag, bits 2-0 table size N (2N+1 entries) |
| 11 | 1 | background color index |
| 12 | 1 | pixel aspect ratio |
The global color table, if present, follows with 3 bytes (RGB) per entry: 2, 4, 8 … 256 entries.
Blocks#
After the header, each block starts with an introducer byte:
| Introducer | Label | Block | Purpose |
|---|---|---|---|
21 |
F9 |
Graphic Control Extension | delay, disposal method and transparent color for the next image |
21 |
FF |
Application Extension | application data, mostly NETSCAPE2.0 (loop count) and XMP DataXMP |
21 |
FE |
Comment Extension | text comment |
21 |
01 |
Plain Text Extension | text rendered on the image; practically unsupported |
2C |
Image Descriptor | position and size of an image (frame), optional local color table, interlace flag, then LZW data | |
3B |
Trailer | end of file |
Extension and image data are stored as sub-blocks: a length byte (1-255) followed by that many bytes, repeated, and ended by a 00 byte. A decoder can skip unknown extensions by reading sub-blocks.
The image descriptor has left, top, width and height (2 bytes each) and a packed byte: bit 7 local color table, bit 6 interlace, bits 2-0 local table size. An image can be smaller than the canvas and placed anywhere on it, which animated GIFs use to store only the changed rectangle.
Animation#
An animated GIF is several image descriptors in one file, each usually preceded by a Graphic Control Extension (GCE):
| GCE field | Meaning |
|---|---|
| Delay | time to show this frame, in 1/100 s. Browsers treat 0 and 1 as 10 (0.1 s), so 2 (20 ms, 50 fps) is the shortest reliable delay |
| Disposal method | what to do with the frame area before drawing the next one: 0 unspecified, 1 keep (draw next frame on top), 2 restore to background (clear to transparent), 3 restore to the previous state |
| Transparent color flag and index | one palette index that is drawn as transparent |
| User input flag | wait for input; ignored by browsers |
Looping is not in the GIF89a spec. The Netscape application extension (NETSCAPE2.0) carries a 2-byte loop count: 0 means loop forever, N means play N more times (browsers differ on whether N counts the first play). Without it, browsers play the animation once.
To show frame N correctly, a decoder must composite frames 0..N-1 on the canvas following each frame’s disposal method. Libraries that return raw frames leave this to you; others (Pillow, ImageMagick -coalesce, image crate) return full composited frames.
Compression#
Pixels are palette indices compressed with variable-length-code LZW (Lempel-Ziv-Welch). The minimum code size byte (2-8) is the number of bits per index; codes start one bit wider and grow up to 12 bits. LZW works well on runs and repeated patterns, poorly on noise and dithering. Interlaced images store rows in 4 passes (every 8th row, then the rows between, and so on) so a slow download shows a coarse preview first.
More than 256 colors#
Each frame can have its own local color table of up to 256 colors, so a file can show more colors by splitting a still image into tiles with different palettes. This works in browsers but makes large files; use PNG instead.
Making GIF files smaller#
- Reduce colors: 64 or 128 colors are often enough for UI recordings. Avoid heavy dithering, which hurts LZW compression.
- Crop each frame to the changed rectangle and use transparency for unchanged pixels. gifsicle
-O3does both. - Lower the frame rate (10-15 fps is enough for screen recordings) and the canvas size.
- Lossy LZW (
gifsicle --lossy=80, gifski for high-quality palettes) cuts size by 30-50% with little visible change. - If the target supports it, use MP4/WebM video, animated WebP or AVIF instead.
Specifications and documentation#
- GIF89a specification (CompuServe, 1990): the current and final version
- GIF87a specification: the original version, without extensions
- What’s in a GIF: byte-by-byte walkthrough with LZW and animation examples
- GIF bits and bytes: every block type, including the Netscape loop extension
- GIFLIB documentation: reference C library and notes on the format
- GIF on Wikipedia
Software that opens GIF files#
| Software | Windows | macOS | Linux | Web | Can | Notes |
|---|---|---|---|---|---|---|
| SumatraPDF | ✓ | view | free, open source; plays animated GIFs; also opens GIF inside archives and comic books | |||
| Web browsers | ✓ | ✓ | ✓ | ✓ | view | Chrome, Edge, Firefox, Safari; animation. Also on Android and iOS |
| Microsoft Photos | ✓ | view | built into Windows, plays animations | |||
| macOS Preview | ✓ | view, convert | built into macOS; shows animation frames as pages | |||
| GIMP | ✓ | ✓ | ✓ | view, edit, create, convert | free, open source; frames as layers | |
| Adobe Photoshop | ✓ | ✓ | view, edit, create, convert | commercial; timeline for animation | ||
| IrfanView | ✓ | view, convert | free for non-commercial use; extract frames | |||
| XnView MP | ✓ | ✓ | ✓ | view, convert | free for private use | |
| ImageMagick | ✓ | ✓ | ✓ | convert, create | command line, open source; -coalesce, -layers Optimize | |
| gifsicle | ✓ | ✓ | ✓ | edit, convert | command-line GIF optimizer and editor, open source | |
| gifski | ✓ | ✓ | ✓ | create | high-quality GIF encoder from video or PNG frames, open source (AGPL) | |
| ScreenToGif | ✓ | create, edit | free, open source screen recorder and GIF editor | |||
| FFmpeg | ✓ | ✓ | ✓ | convert, create | convert video to GIF and GIF to MP4/WebM, command line | |
| Photopea | ✓ | view, edit, create, convert | free, runs in the browser | |||
| ezgif | ✓ | edit, convert | online GIF maker, optimizer and converter |
Libraries#
Open-source libraries that read and write GIF, including animated GIF. See all GIF libraries for a comparison.
| C/C++ | GIFLIB, stb_image |
|---|---|
| C# | ImageSharp, Magick.NET |
| Java | ImageIO |
| Go | image/gif |
| Python | Pillow |
| Ruby | MiniMagick, ruby-vips |
| Rust | gif, image |
| PHP | GD, Imagick, Intervention Image |