Skip to content

Instantly share code, notes, and snippets.

@xnuk
Created October 14, 2018 03:15
Show Gist options
  • Save xnuk/c0766a01c638bc82176f6e2c4022eb9e to your computer and use it in GitHub Desktop.
Save xnuk/c0766a01c638bc82176f6e2c4022eb9e to your computer and use it in GitHub Desktop.
const startBufferLength = 0x20
const startBuffer = Buffer.from([
0x42, 0x4d, // magic ('BM')
0x00, 0x00, 0x00, 0x00, // length -- @2
0x00, 0x00, 0x00, 0x00, // should be [0u16, 0u16].
startBufferLength, 0x00, 0x00, 0x00, // offset
// dib
0x0c, 0x00, 0x00, 0x00, // dib length
0x00, 0x00, // width -- @18
0x00, 0x00, // height -- @20
0x01, 0x00, // should be 1u16
0x01, 0x00, // color bits
// palette
0xff, 0xff, 0xff, // white - 0
0x00, 0x00, 0x00, // black - 1
])
export const render = (data: (0|1)[][]): Buffer => {
const width = data[0].length
const height = data.length
// data with given color bits (1 bit),
// and add some paddings to make the row length into multiple of 4 bytes
// ceil(bytes / 4) * 4 where bytes = width * color_bits / 8
const bitmapRowLength = Math.ceil(width / 32) * 4
const bitmapLength = bitmapRowLength * height
const newBuffer = Buffer.from(startBuffer)
newBuffer.writeUInt32LE(bitmapLength + startBufferLength, 2)
newBuffer.writeUInt16LE(width, 18)
newBuffer.writeUInt16LE(height, 20)
const dataBytes = data.map(v => {
const buf = Buffer.alloc(bitmapRowLength, 0)
const len = v.length
for (let i = 0; i*8 < len; ++i) {
// bits to octets
const data = v.slice(i * 8, (i+1) * 8).reduce(
(st, v, i) => st | v << 8-1-i,
0 as number
)
buf.writeUInt8(data, i)
}
return buf
// https://stackoverflow.com/questions/8346115/why-are-bmps-stored-upside-down
}).reverse()
dataBytes.unshift(newBuffer)
return Buffer.concat(dataBytes)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment