![]() |
VOOZH | about |
27 January 2011
This post explains how to generate bitmap images byte-by-byte in JavaScript. It’s mostly just a coding exercise since the canvas element actually has this functionality built-in. I used this technique to generate images in my low res paint app and favicon creator. If you hate prose, then check out the bitmap generation source code directly.
A byte is 8 bits, 2^8 = 256 possible values, as you all know that's conveniently represented as two hex characters—0x00 is 0 and 0xff is 255.
In JavaScript you can write that with a string as such: '\x00' or '\xff' or even '\xff\x00\x00' which can represent the RGB value for red.
'\x00' // 0 '\xff' // 255 '\xff\x00\x00' // the RGB value for red
Note:
'\x' + '00' != '\x00' // false '\x' + '00' === 'x00' // true - we can’t represent bytes this way
To create byte strings dynamically, you can use String.fromCharCode()
String.fromCharCode(255) === '\xff' // true - this is the way to do it
Note: going above 255 stops producing characters that you can use as bytes, but it still produces some fun stuff, like the snowman character:
String.fromCharCode(9731) === '☃'
So to get bytes for numbers that are larger than 255, you have to break it up into chunks and do each chunk:
String.fromCharCode(value & 255); // get the last byte using a mask value >>= 8; // then shift value to the next byte
Bitmap seemed to be the simplest image format (specifically 24-bit bitmaps—24-bit, i.e., 3-bytes, i.e., RGB), there’s no compression, it’s mostly just a map of bits—I found everything I needed to know on this wikipedia page.
Bitmaps consist of a (52 byte) header that describes stuff about the file and then rows of pixel data as RGB values
Integer values are represented as little-endian (least significant byte first)
value big-endian little-endian 266 '\x01\x0a' '\x0a\x01' red '\xff\x00\x00' '\x00\x00\xff'
Bitmap data starts at the lower left of the image (and reads across rows)
Each row of the bitmap needs to be padded to be a multiple of 4 bytes (since RGB is 3 bytes, this is very common)
The data url scheme allows you to represent pretty much any media as a string.
// data:[<mediatype>][;base64],<base64_encoded_data> var src = 'data:image/bmp;base64,' + myBase64EncodedData;
The final piece of the puzzle—btoa()—this magically converts stuff to base64, et voilà, we have an image.
var src = 'data:image/bmp;base64,' + btoa(myData);
See this code in action in the low res paint app and also in the favicon creator. You can also check out the actual bitmap generation source code to see how the header and the data are handled.
is a software engineer living in NYC who is building
Superset 💪
and also created
GoFullPage 📸
more »
github · soundcloud · rss
mrcoles.com © 2026