Add a Comment to a GIF
Add custom text comments and captions to animated GIF images. Overlay styled text on every frame with live preview and download.
About
Animated GIFs store frames as indexed-color images using the GIF89a specification with LZW-compressed pixel data. Adding text to a GIF requires decoding every frame, rendering the overlay via a rasterization pass, then re-encoding the modified frames back into a valid binary stream with correct Graphics Control Extension blocks preserving original delay values (in hundredths of a second) and disposal methods. Getting this wrong produces garbled frames, broken transparency, or corrupted files that won't play. This tool performs full binary-level GIF parsing and re-encoding entirely in your browser. No server upload occurs. Frame count, color table depth (up to 256 colors per frame), and inter-frame timing are preserved. Note: re-quantization to 256 colors may introduce minor dithering artifacts on photographic-quality GIFs.
Formulas
Each frame in a GIF is stored as an indexed-color image. The pixel buffer size is computed from the frame dimensions:
where width and height are the frame dimensions in pixels. Each pixel maps to a color table index (0 - 255).
LZW compression uses a dictionary that grows from an initial size of 2minCodeSize + 1 entries. The clear code and end-of-information code are defined as:
where minCodeSize is the LZW minimum code size stored in the image sub-block (typically 2 to 8).
Frame delay in milliseconds is derived from the stored value:
Text overlay position is stored as normalized coordinates to allow repositioning:
where xnorm and ynorm are values between 0 and 1.
Reference Data
| Property | GIF89a Spec Value | Notes |
|---|---|---|
| Max Colors per Frame | 256 | Indexed palette constraint |
| LZW Min Code Size | 2 - 8 bits | Defined per image sub-block |
| Frame Delay Unit | 10 ms | Stored as hundredths of a second |
| Default Delay (if 0) | 100 ms | Browsers typically use ~100ms |
| Max Image Size | 65535 × 65535 px | 16-bit unsigned per dimension |
| Transparency | 1-bit flag | One palette index = transparent |
| Disposal Method 0 | Unspecified | No disposal action |
| Disposal Method 1 | Do Not Dispose | Frame persists under next |
| Disposal Method 2 | Restore to Background | Clear to background color |
| Disposal Method 3 | Restore to Previous | Restore canvas to prior state |
| Header Signature | GIF89a | 6-byte ASCII identifier |
| Trailer Byte | 0x3B | Marks end of GIF stream |
| Extension Introducer | 0x21 | Precedes all extension blocks |
| Image Separator | 0x2C | Precedes each image descriptor |
| Graphic Control Ext. | 0xF9 | Label for frame timing/disposal |
| Comment Extension | 0xFE | Embeds text metadata in stream |
| Application Extension | 0xFF | Used for NETSCAPE looping block |
| NETSCAPE Loop Count | 0 = infinite | Sub-block of Application Ext. |
| Interlace Pattern | 4-pass | Rows: 0,8,4,2 then fill |
| Typical Web GIF Size | < 5 MB | Larger files cause slow decode |