Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generate a monochrome bitmap image in JavaScript using a byte-array. The image is generated such that every bit in the array is shown as either a black (1) or white (0) pixel.
/**
* depth: 1 - monochrome
* 4 - 4-bit grayscale
* 8 - 8-bit grayscale
* 16 - 16-bit colour
* 32 - 32-bit colour
**/
function drawArray(arr, depth) {
var offset, height, data, image;
function conv(size) {
return String.fromCharCode(size&0xff, (size>>8)&0xff, (size>>16)&0xff, (size>>24)&0xff);
}
offset = depth <= 8 ? 54 + Math.pow(2, depth)*4 : 54;
height = Math.ceil(Math.sqrt(arr.length * 8/depth));
//BMP Header
data = 'BM'; // ID field
data += conv(offset + arr.length); // BMP size
data += conv(0); // unused
data += conv(offset); // pixel data offset
//DIB Header
data += conv(40); // DIB header length
data += conv(height); // image height
data += conv(height); // image width
data += String.fromCharCode(1, 0); // colour panes
data += String.fromCharCode(depth, 0); // bits per pixel
data += conv(0); // compression method
data += conv(arr.length); // size of the raw data
data += conv(2835); // horizontal print resolution
data += conv(2835); // vertical print resolution
data += conv(0); // colour palette, 0 == 2^n
data += conv(0); // important colours
//Grayscale tables for bit depths <= 8
if (depth <= 8) {
data += conv(0);
for (var s = Math.floor(255/(Math.pow(2, depth)-1)), i = s; i < 256; i += s) {
data += conv(i + i*256 + i*65536);
}
}
//Pixel data
data += String.fromCharCode.apply(String, arr);
//Image element
image = document.createElement('img');
image.src = 'data:image/bmp;base64,' + btoa(data);
return image;
}
/*Usage example, visualize random numbers generated by Math.random */
for (var a= [], i = 0; i < 8192; i++) {
a[i] = Math.floor(Math.random()*256);
}
document.body.appendChild(drawArray(a, 1));
document.body.appendChild(drawArray(a, 4));
document.body.appendChild(drawArray(a, 8));
document.body.appendChild(drawArray(a, 16));
document.body.appendChild(drawArray(a, 32));
@kalzso

This comment has been minimized.

Copy link

kalzso commented Oct 28, 2014

Helo Vukicevic!

This is awesome, can you make it even better? For example to make it colored instead of monochrome?

Pozdrav ;)

@vukicevic

This comment has been minimized.

Copy link
Owner Author

vukicevic commented Nov 19, 2014

Hi!

I've updated this gist to add some colour support, but it's a tricky problem. You can create 1,4,8 bit grayscale or 16 or 32 bit colour as output.

There are padding issues at different bit lengths, which would make the code much longer. 2-bit grayscale doesn't work for some reason, I don't have time to debug, you can fix it if you wish.

@ApoorvaJ

This comment has been minimized.

Copy link

ApoorvaJ commented Jan 5, 2016

Small correction: Comments on line 26 and 27 are incorrect. Width should be specified before height in DIB header.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.