79130315

Date: 2024-10-27 10:06:39
Score: 0.5
Natty:
Report link

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}

}

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): user1693593
  • Low reputation (1):
Posted by: tomer.shatz