Converting to bmp 24bpp inpired by user1693593 answer:
static toArrayBuffer24bpp(canvas: HTMLCanvasElement): ArrayBuffer {
var w = canvas.width,
h = canvas.height,
w4 = w * 4,
idata = canvas.getContext("2d").getImageData(0, 0, w, h),
data32 = new Uint32Array(idata.data.buffer), // 32-bit representation of canvas
stride24 = Math.floor((24 * w + 31) / 32) * 4, // row length incl. padding
pixelArraySize = stride24 * h, // total bitmap size
fileLength = 122 + pixelArraySize, // header size is known + bitmap
file = new ArrayBuffer(fileLength), // raw byte buffer (returned)
view = new DataView(file), // handle endian, reg. width etc.
pos = 0, x, y = 0, p, s = 0, v, r, g, b, x2;
// write file header
setU16(0x4d42); // BM
setU32(fileLength); // total length
pos += 4; // skip unused fields
setU32(0x7a); // offset to pixels
// DIB header
setU32(108); // header size
setU32(w);
setU32(-h >>> 0); // negative = top-to-bottom
setU16(1); // 1 plane
setU16(24); // 24-bits
setU32(0); // BI_RGB = 0
setU32(pixelArraySize); // bitmap size incl. padding (stride x height)
setU32(2835); // pixels/meter h (~72 DPI x 39.3701 inch/m)
setU32(2835); // pixels/meter v
pos += 8; // skip color/important colors
setU32(0xff0000); // red channel mask
setU32(0xff00); // green channel mask
setU32(0xff); // blue channel mask
setU32(0xff000000); // alpha channel mask
setU32(0x57696e20); // " win" color space
// bitmap data, change order of ABGR to BGRA
while (y < h) {
p = 0x7a + y * stride24; // offset + stride x height
x = 0;
x2 = 0
while (x < w4) {
v = data32[s++]; // get ABGR
b = v & 0xff
g = (v >> 8) & 0xff
r = (v >> 16) & 0xff
view.setUint8(p + x2++, r)
view.setUint8(p + x2++, g)
view.setUint8(p + x2++, b)
x += 4;
}
y++
}
return file;
// helper method to move current buffer position
function setU16(data) {view.setUint16(pos, data, true); pos += 2}
function setU32(data) {view.setUint32(pos, data, true); pos += 4}
}