Really basic JavaScript library written in ECMAScript 2017 for parsing GIF (/gɪf/ not /ˈdʒɪf/) files.
fetch("//url.to/my.gif") /* request for a GIF file, can also be a filesystem
* read if you use Node or similar */
.then(GIF)
.then(async (gifObj) => {
// code to manipulate raw GIF data
const inflatedFrameData = await gifObj.inflate(0);
/* returns an array containing decompressed color codes of the first
* frame and also expands the frame's object with this array
* gifObj.frames[0].data === inflatedFrameData => true */
const deinterlacedFrameData = await gifObj.deinterlace(0);
/* returns an array containing deinterlaced color codes of the first
* frame and also expands the frame's object with this array
* gifObj.frames[0].deinterlacedData === deinterlacedFrameData => true
*
* please note that you can call this function without calling
* .inflate() first, because it will call it for you when the `data`
* property is missing */
const imageData = await gifObj.toImageData(0);
/* returns an ImageData object ready to be used in a <canvas>
* using this will NOT extend gifObj.frames[0] with an properties
*
* please note that you can call this function without calling
* .inflate() first *and .deinterlace() if necessary*, because it
* will call them for you when necessary */
})
You'll notice that the Response
object can be passed directly to the GIF
function. This is because GIF
has a property (GIF.Response
) which will be
checked using instanceof
against the first argument. If it matches, then the
[GIF.responseMethod]
method of the input will be called, which is by default
arrayBuffer
, to compliment fetch
in the browsers perfectly. Obviously, you
may change this as you wish depending on what you use to make requests.
I needed a versatile library to process GIFs for personal use, but the already available libraries out there all came with extra fluff that made it look difficult to achieve what I wanted using them.
GIF
will resolve into an Object
if successfull. Will be referenced
as gifObj
from here on out. Please do note that a gifObj
contains function
methods and Symbol
properties, so structured clone algorithm will fail to
copy it properly to a worker. Importing the library into a worker itself is
recommended instead.
These methods are, non-enumerable, non-configurable and non-writeable properties
of gifObj
. They are also asynchronous, non-generic functions that will throw
if this
is not a gifObj
.
-
inflate
: accepts two parametersindex, ?clearRawData
index
: index of the frame to be processed, must be anint
bigger than0
, will throw otherwise
?clearRawData
: if this parameter is set to any truthy value, then therawData
property ofgifObj.frames[index]
will be set tovoid 0
Returns an
Array
containing the LZW decompressed color codes of the frame and expandsgifObj.frames[index]
with this array to thedata
property. -
deinterlace
: accepts two parametersindex, ?overwriteData
index
: index of the frame to be processed, must be anint
bigger than0
, will throw otherwise
?overwriteData
: if this parameter is set to any truthy value, then thedata
property ofgifObj.frames[index]
will be overwritten with the resultReturns an
Array
containing the deinterlaced color codes of the frame and expandsgifObj.frames[index]
with this array to thedeinterlacedData
property. IfoverwriteData
is true, thendata
will contain the result anddeinterlacedData
will be set tonull
. If the user didn't use.inflate()
, then this function will do that with the optional parameter (clearRawData
) set to true, to avoid needlessly taking up memory space. This method will only be called if the user omitted preprocessing the frames themselves. -
toImageData
: accepts one parameterindex
index
: index of the frame to be processed, must be anint
bigger than0
, will throw otherwiseReturns an
Array
with this structure:[ImageData, offsetLeft, offsetTop]
. It is recommended to destructure this array as parameters like soctx.putImageData(...gifObj.toImageData(0))
. If the user didn't use.inflate()
or.deinterlace()
if needed, then this function will do that with both optional parameters (clearRawData
,overwriteData
) set to true, to avoid needlessly taking up memory space. These methods will only be called if the user omitted preprocessing the frames themselves.
Property names are in line with the GIF specification, for more detailed
explanation follow the link. gifObj
also contains 2 Symbol
properties for
internal uses.
descriptor
: object containing theLogical Screen Descriptor
- type:Object
width
: width of the GIF - type:uint16
height
: height of the GIF - type:uint16
backgroundColorIndex
: type:uint8
pixelAspectRatio
: type:uint8
packed
: the packed byte - type:Object
globalColorTableFlag
: indicates whether aGlobal Color Table
is present or not - type:int
,0
or1
colorResolution
: type:int
sortFlag
: indicates whether theGlobal Color Table
is sorted or not - type:int
,0
or1
size
: indicates the size ofGlobal Color Table
(2 ** ( size + 1 )
) - type:int
,0-7
globalColorTable
: type:Array
ifglobalColorTableFlag
equals1
, otherwiseundefined
individual colors are stored inArray
s with the length of3
repeat
: number of times for the GIF to be repeated, where0
means repeat forever - type:uint8
frames
: array containing the frames of the GIF - type:Array
The details of the frames are stored in an Object
.
graphicExtension
: object containing theGraphics Control Extension
- type:Object
disposalMethod
: type:int
,0-7
userInputFlag
: type:int
,0
or1
transparentColorFlag
: type:int
,0
or1
delay
: the duration of which the frame should be displayed for in milliseconds - type:int
transparentColorIndex
: type:uint8
descriptor
: object containing theImage Descriptor
- type:Object
left
: offset of the Image Data from the left of the GIF - type:uint16
top
: offset of the Image Data from the top of the GIF - type:uint16
width
: width of the Image Data - type:uint16
height
: height of the Image Data - type:uint16
packed
: the packed byte - type:Object
localColorTableFlag
: indicates whether aLocal Color Table
is present or not - type:int
,0
or1
interlaceFlag
: indicates whether the color codes are interlaced or not - type:int
,0
or1
sortFlag
: indicates whether theLocal Color Table
is sorted or not - type:int
,0
or1
size
: indicates the size ofLocal Color Table
(2 ** ( size + 1 )
) - type:int
,0-7
localColorTable
: type:Array
iflocalColorTableFlag
equals1
, otherwiseundefined
individual colors are stored inArray
s with the length of3
minCodeSize
: minimum code size required for color table building - type:uint8
,2-8
rawData
: contains the concatenated Image Data sub-blocks - type:Array
, will beundefined
if you call.inflate(index, true)
individual bytes are stored asuint8
sdata
: contains decompressed color codes - type:Array
if.inflate()
was called, otherwiseundefined
individual codes are stored asuint8
sdeinterlacedData
: contains deinterlaced color codes - type:Array
if.deinterlace()
was called ornull
if.deinterlace(index, true)
was called, otherwiseundefined
individual codes are stored asuint8
s
See the project page on my GitHub Pages for an example usage. Worker addition can be found in this Gist.
What's In A GIF - Bit by Byte - Very easy to understand and detailed blog
by Matthew Flickinger
gifuct-js - LZW and deinterlace by Matt Way
WTFPL