GIF decoding and rendering with HTML5 canvas
Here is a link to the live website for the GIF decoder/player, with URL parameters as specified below.
Also, see the specs for GIF89a and What's In A GIF: GIF Explorer
by @MrFlick for more technical details.
URL parameters can be in any order, starting with ?
after the URL and then parameters in the format NAME=VALUE
with &
between each parameter.
Note
Values must be encoded URI components.
Parameters with values 0
/1
can omit the =VALUE
for it to be treated as 1
.
For example ?url=https%3A%2F%2Fexample.com%2Fexample.gif&gifInfo=0&frameInfo
translates to:
Name | Decoded value |
---|---|
url |
https://example.com/example.gif |
gifInfo |
0 (collapsed) |
frameInfo |
1 (expanded) |
Click to toggle table
Name | Possible values | Description | Default value |
---|---|---|---|
url |
a GIF file URL | GIF URL to load | This public domain GIF from Wikimedia |
gifInfo |
0 collapsed / 1 expanded |
If the GIF info section should be expanded | 1 (expanded) |
globalColorTable |
0 collapsed / 1 expanded |
If the Global color table section should be expanded | 1 (expanded) |
appExtList |
0 collapsed / 1 expanded |
If the Application-Extensions section should be expanded | 1 (expanded) |
commentsList |
0 collapsed / 1 expanded |
If the Comments section should be expanded | 0 (collapsed) |
unExtList |
0 collapsed / 1 expanded |
If the Unknown extensions section should be expanded | 0 (collapsed) |
frameView |
0 collapsed / 1 expanded |
If the frame canvas section should be expanded | 0 (collapsed) |
frameInfo |
0 collapsed / 1 expanded |
If the Frame info section should be expanded | 0 (collapsed) |
localColorTable |
0 collapsed / 1 expanded |
If the local color table section should be expanded | 1 (expanded) |
frameText |
0 collapsed / 1 expanded |
If the (Frame) Text section should be expanded | 0 (collapsed) |
import |
0 closed / 1 open |
If the import menu should be opened | 0 (closed) |
play |
float between -100 and 100 <0 reversed / >0 (or empty) forwards |
If the GIF should be playing, how fast, and in what direction | 0 (paused) |
f |
zero-based frame index (positive integer) if out of bounds uses first frame |
Start at a specific frame | 0 (first frame) |
userLock |
0 OFF / 1 ON |
If the user input lock button should be toggled on | 0 (OFF) |
gifFull |
0 OFF / 1 ON |
If the GIF full window button should be toggled on | 0 (OFF) |
gifReal |
0 OFF / 1 ON |
If the GIF fit window button should be toggled on | 0 (OFF) |
gifSmooth |
0 OFF / 1 ON |
If the GIF img smoothing should be toggled on | 0 (OFF) |
frameFull |
0 OFF / 1 ON |
If the frame full window button should be toggled on | 0 (OFF) |
frameReal |
0 OFF / 1 ON |
If the frame fit window button should be toggled on | 0 (OFF) |
frameSmooth |
0 OFF / 1 ON |
If the frame img smoothing button should be toggled on | 0 (OFF) |
pos |
integer,integer |
The position/offset of the GIF/frame rendering canvas (left,top safe integers) |
0,0 (origin) |
zoom |
float | The starting zoom of the GIF/frame rendering canvas (clamped to +- 500) calculation: canvas_width = GIF_width * (e ↑ (zoom / 100)) |
0 (no zoom) |
- If, during decoding, an error occurs, it will show the import menu and display the error without further decoding/rendering (ignore all parameters, except for collapsible areas)
- If
import
is given only allowurl
and collapsable areas (ignore all other parameters)- When the import menu is open, the GIF is not yet decoded (only a preview is shown)
- If
gifReal
andframeReal
are both0
(OFF) ignorepos
andzoom
- If
gifFull
is1
(ON) ignoreframeFull
- If
frameFull
is1
(ON) ignoreframeView
- If
frameView
is0
(collapsed) ignoreframeReal
andframeSmooth
- If
pos
andzoom
are given, applypos
beforezoom
- If, during decoding, an error occurs, it will show the import menu and display the error without further decoding/rendering
Exported constants in the GIFdecodeModule.js
file.
See description/type information further below.
Decodes a GIF into its components for rendering on a canvas.
async decodeGIF(gifURL, avgAlpha, fetchProgressCallback, sizeCheck, progressCallback)
function parameters (in order)
-
gifURL
(string
) The URL of a GIF file. -
avgAlpha
(optionalboolean
) If this istrue
then, when encountering a transparent pixel, it uses the average value of the pixels RGB channels to calculate the alpha channels value, otherwise alpha channel is either 0 or 1. Defaultfalse
. -
fetchProgressCallback
(optionalfunction
) Optional callback for showing progress of fetching the image data (in bytes).function( loaded: number, // amount of bytes loaded total: number | null // total amount of bytes to load (or null if not available) ): any
-
sizeCheck
(optionalfunction
) Optional check if the loaded file should be processed if this yieldsfalse
then it will reject withfile to large
function( byteLength: number // size of file in bytes ): Promise<boolean> | boolean // continues decoding with `true`
-
progressCallback
(optionalfunction
) Optional callback for showing progress of decoding process (when GIF is interlaced calls after each pass (4x on the same frame)). If asynchronous, it waits for it to resolve.function( percentageRead: number, // decimal from 0 to 1 frameIndex: number, // zero-based frame index frame: ImageData, // current decoded frame (image) framePos: [number, number], // pos from left/top of GIF area gifSize: [number, number] // GIF area width/height ): any
Returns (GIF
) a promise of the GIF
with each frame decoded separately.
The promise may reject for one the following reasons:
fetch error
when trying to fetch the GIF fromgifURL
(probably blocked by CORS security options)fetch aborted
when trying to fetch the GIF fromgifURL
loading error [CODE]
when URL yields a status code that's not between 200 and 299 (inclusive)file to large
whensizeCheck
yieldsfalse
not a supported GIF file
when it's not a GIF file or the version is notGIF89a
error while parsing frame [INDEX] "ERROR"
while decoding GIF - one of the followingGIF frame size is to large
plain text extension without global color table
undefined block found
Throws (TypeError
) for one of the following (in order)
gifURL
is not a stringavgAlpha
is given (notnull
orundefined
) but not a booleanfetchProgressCallback
is given (notnull
orundefined
) but not a functionsizeCheck
is given (notnull
orundefined
) but not a functionprogressCallback
is given (notnull
orundefined
) but not a function
Extract the animation loop amount from a GIF
.
Note
Generally, for proper looping support, the NETSCAPE2.0
extension must appear immediately after the global color table of the logical screen descriptor (at the beginning of the GIF file).
Still, here, it doesn't matter where it was found.
getGIFLoopAmount(gif)
function parameters (in order)
gif
(GIF
) A parsed GIF object.
Returns (number
) the loop amount of gif
as 16bit number (0 to 65'535 or Infinity
).
The GIF
object constructed has the following attributes.
Click to toggle table
Attribute | JSDoc annotation | Description |
---|---|---|
width |
number |
the width of the image in pixels (logical screen size) |
height |
number |
the height of the image in pixels (logical screen size) |
totalTime |
number |
the (maximum) total duration of the gif in milliseconds (all delays added together) will be Infinity if there is a frame with the user input delay flag set and no timeout |
colorRes |
number |
the color depth/resolution in bits per color (in the original) [1-8 bits] |
pixelAspectRatio |
number |
if non zero the pixel aspect ratio will be from 4:1 to 1:4 in 1/64th increments |
sortFlag |
boolean |
if the colors in the global color table are ordered after decreasing importance |
globalColorTable |
[number,number,number][] |
the global color table for the GIF |
backgroundColorIndex |
number|null |
index of the background color into the global color table (if the global color table is not available it's null ) can be used as a background before the first frame |
frames |
Frame[] |
each frame of the GIF (decoded into single images) type information further below |
comments |
[string,string][] |
comments in the file and were they where found ([<area found>,<comment>] ) |
applicationExtensions |
ApplicationExtension[] |
all application extensions found type information further below |
unknownExtensions |
[number,Uint8Array][] |
all unknown extensions found ([<identifier>,<raw bytes>] ) |
Click to toggle table
Attribute | JSDoc annotation | Description |
---|---|---|
left |
number |
the position of the left edge of this frame, in pixels, within the gif (from the left edge) |
top |
number |
the position of the top edge of this frame, in pixels, within the gif (from the top edge) |
width |
number |
the width of this frame in pixels |
height |
number |
the height of this frame in pixels |
disposalMethod |
DisposalMethod |
the disposal method for this frame type information further below |
transparentColorIndex |
number|null |
the transparency index into the local or global color table (null if not encountered) |
image |
ImageData |
this frames image data |
plainTextData |
PlainTextData|null |
the text that will be displayed on screen with this frame (null if not encountered) type information further below |
userInputDelayFlag |
boolean |
if set waits for user input before rendering the next frame (timeout after delay if that is non-zero) |
delayTime |
number |
the delay of this frame in milliseconds (0 is undefined (wait for user input or skip frame) - 10 ms precision) |
sortFlag |
boolean |
if the colors in the local color table are ordered after decreasing importance |
localColorTable |
[number,number,number][] |
the local color table for this frame |
reserved |
number |
reserved for future use 2bits (from packed field in image descriptor block) |
GCreserved |
number |
reserved for future use 3bits (from packed field in graphics control extension block) |
Click to toggle table
Name | Internal value ( number ) |
Description | Action |
---|---|---|---|
Unspecified |
0 |
unspecified | do nothing (default to DoNotDispose ) |
DoNotDispose |
1 |
do not dispose | keep image / combine with next frame |
RestoreBackgroundColor |
2 |
restore to background color | opaque frame pixels get filled with background color or cleared (when it's the same as transparentColorIndex ) |
RestorePrevious |
3 |
restore to previous | dispose frame data after rendering (revealing what was there before) |
UndefinedA |
4 |
undefined | fallback to Unspecified |
UndefinedB |
5 |
undefined | fallback to Unspecified |
UndefinedC |
6 |
undefined | fallback to Unspecified |
UndefinedD |
7 |
undefined | fallback to Unspecified |
Click to toggle table
Attribute | JSDoc annotation | Description |
---|---|---|
left |
number |
the position of the left edge of text grid (in pixels) within the GIF (from the left edge) |
top |
number |
the position of the top edge of text grid (in pixels) within the GIF (from the top edge) |
width |
number |
the width of the text grid (in pixels) |
height |
number |
the height of the text grid (in pixels) |
charWidth |
number |
the width (in pixels) of each cell (character) in text grid |
charHeight |
number |
the height (in pixels) of each cell (character) in text grid |
foregroundColor |
number |
the index into the global color table for the foreground color of the text |
backgroundColor |
number |
the index into the global color table for the background color of the text |
text |
string |
the text to render on screen |
Click to toggle table
Attribute | JSDoc annotation | Description |
---|---|---|
identifier |
string |
8 character string identifying the application |
authenticationCode |
string |
3 bytes to authenticate the application identifier |
data |
Uint8Array |
the (raw) data of this application extension |