Skip to content

Instantly share code, notes, and snippets.

@arcollector
Last active August 29, 2015 14:20
Show Gist options
  • Save arcollector/71be4048fc5a9e1980e5 to your computer and use it in GitHub Desktop.
Save arcollector/71be4048fc5a9e1980e5 to your computer and use it in GitHub Desktop.
BMP file creation in js
function long2LittleEndian( val ) {
return new Uint8Array( [ val & 0x000000ff, (val & 0x0000ff00) >> 8, (val & 0x00ff0000) >> 16, (val & 0xff000000) >> 24 ] );
}
function bmp( width, height, canvas ) {
var extraBytes = width % 4,
canvaSize = height*(width*3 + extraBytes),
fileSize = 54 + canvaSize,
fz = long2LittleEndian( fileSize ),
w = long2LittleEndian( width ),
h = long2LittleEndian( height ),
data = new Uint8Array( fileSize );
data.set( [
66,77, // 'BM'
fz[0],fz[1],fz[2],fz[3], // file size in long in little endian
0,0, // always 0
0,0, // always 0
54,0,0,0, // canvas image starting address, 54 for 24 bits images
40,0,0,0, // header size, always 40
w[0],w[1],w[2],w[3], // width in long in little endian
h[0],h[1],h[2],h[3], // height
1,0, // image planes, always 1
24,0, // 24 bits color depth
0,0,0,0, // compression type, 0 for uncompressed
0,0,0,0, // ignore these fields
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
], 0 );
var x, y,
i, address,
canvasBMP = new Uint8Array( canvaSize );
for( i = 0, y = height - 1; y >= 0; y-- ) {
for( x = 0; x < width; x++ ) {
address = 4*(y*width + x);
canvasBMP[i++] = canvas[address + 2];
canvasBMP[i++] = canvas[address + 1];
canvasBMP[i++] = canvas[address];
}
for( x = 0; x < extraBytes; x++ ) {
canvasBMP[i++] = 0;
}
}
data.set( canvasBMP, 54 );
return data;
}
function download( arrayBuffer ) {
var $a = document.createElement( 'a' );
$a.setAttribute( 'download', +new Date() + '.bmp' );
$a.setAttribute( 'href', URL.createObjectURL( new Blob( [ arrayBuffer ], { type: 'application/octet-binary' } ) ) );
$a.style.display = 'none';
document.body.appendChild( $a );
$a.click();
document.body.removeChild( $a );
}
function randomImage( width, height ) {
var canvas = new Uint8Array( width*height*4 ),
i, r, g, b, x, y,
left, top, bottom, right, maxX, maxY,
blockSize = 16, address,
rows = Math.ceil( height/blockSize ),
cols = Math.ceil( width/blockSize );
for( i = 0; i < rows*cols; i++ ) {
r = ~~(Math.random() * 256);
g = ~~(Math.random() * 256);
b = ~~(Math.random() * 256);
left = ~~(i/rows)*blockSize;
top = ~~(i%rows)*blockSize;
right = blockSize + left;
bottom = blockSize + top;
maxY = Math.min( bottom, height );
maxX = Math.min( right, width );
for( y = top; y < maxY; y++ ) {
address = 4*(y*width + left);
for( x = left; x < maxX; x++ ) {
canvas[address++] = r;
canvas[address++] = g;
canvas[address++] = b;
canvas[address++] = 255;
}
}
}
// DEBUG
var $canvas = document.createElement( 'canvas' );
$canvas.width = width;
$canvas.height = height;
var ctx = $canvas.getContext( '2d' );
var image = ctx.getImageData( 0,0, width, height );
for( var i = 0, j = 0; i < canvas.length; ) {
image.data[i++] = canvas[j++];
image.data[i++] = canvas[j++];
image.data[i++] = canvas[j++];
image.data[i++] = canvas[j++];
}
ctx.putImageData( image, 0,0 );
document.body.appendChild( $canvas );
return canvas;
}
width = 1920;
height = 1080;
download( bmp( width, height, randomImage( width, height ) ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment