Created
September 15, 2023 00:27
-
-
Save LingDong-/e0a312fd826d28ac68c51a33fbfd40a9 to your computer and use it in GitHub Desktop.
minimal animated GIF encoder in 50 lines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// encode_anim_gif.js | |
// minimal code to make animated GIFs from arrays of pixels | |
// - no compression | |
// - supports 127 colors (127 shades of gray by default) | |
function encode_anim_gif(frames,w,h,delay=5){ | |
let bytes = []; | |
bytes.push(0x47,0x49,0x46,0x38,0x39,0x61); | |
bytes.push(w&0xff); | |
bytes.push((w>>8)&0xff); | |
bytes.push(h&0xff); | |
bytes.push((h>>8)&0xff); | |
bytes.push(0xf6); | |
bytes.push(0,0); | |
for (let i = 0; i < 127; i++){ | |
bytes.push(i*2,i*2,i*2); //change this for alternative color table | |
} | |
bytes.push(0xff,0xff,0xff); | |
bytes.push(0x21,0xff,0x0b); | |
bytes.push(0x4E,0x45,0x54,0x53,0x43,0x41,0x50,0x45,0x32,0x2E,0x30); | |
bytes.push(0x03,0x01,0xff,0xff,0x00); | |
for (let k = 0; k < frames.length; k++){ | |
let data = frames[k]; | |
bytes.push(0x21,0xf9,0x04,0b00000100); | |
bytes.push(delay&0xff); // change this for different delay each frame | |
bytes.push((delay>>8)&0xff); | |
bytes.push(0xff,0x00); | |
bytes.push(0x2c,0,0,0,0); | |
bytes.push(w&0xff); | |
bytes.push((w>>8)&0xff); | |
bytes.push(h&0xff); | |
bytes.push((h>>8)&0xff); | |
bytes.push(0,7); | |
let n = ~~(w*h/126); | |
let inc = n*126; | |
let exc = w*h-inc; | |
for (let i = 0; i < n; i++){ | |
bytes.push(0x7f,0x80); | |
for (let j = 0; j < 126; j++){ | |
bytes.push(~~(data[i*126+j]/2)); | |
} | |
} | |
if (exc){ | |
bytes.push(exc+1); | |
bytes.push(0x80); | |
for (let i = 0; i < exc; i++){ | |
bytes.push(~~(data[inc+i]/2)); | |
} | |
} | |
bytes.push(0x01,0x81,0x00); | |
} | |
bytes.push(0x3B); | |
return bytes; | |
} | |
// ------ end library ------- | |
// ----- begin example ------ | |
let frames = []; | |
let W = 255; | |
let H = 255; | |
for (let k = 0; k < 100; k++){ | |
let data = []; | |
for (let i = 0; i < H; i++){ | |
for (let j = 0; j < W; j++){ | |
data.push((j+k*5)%255); | |
} | |
} | |
frames.push(data); | |
} | |
const fs = require('fs'); | |
fs.writeFileSync("test.gif",Buffer.from(encode_anim_gif(frames,W,H,10))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment