|Written by Ian Elliot|
|Monday, 19 August 2013|
Page 2 of 4
Converting Bits To Bitmap
The first thing to do is associate a DataView with the buffer and create an empty object to hold the Bitmap data:
Next we have to start decoding the BMP format. BMP files always start with two headers - a Bitmap File Header followed by a DIB header. The data follows the headers but there are a number of optional entries that could come after the two headers.
The format of the Bitmap Header (Wikipedia) is:
As you can see the first field should be BM in ASCII for all of the files you are going to work with. The second is the total file size not the image size and the last field gives the starting location of the pixel data.
Using the dataview that we have already created it is now easy to convert the bits into the fields of the bitmap object:
Notice that the final "endian" parameter has to be true because BMP files are always stored in Little Endian order and this has to be converted into whatever order the machine that the program is running on uses.
The second header records information about the pixel data and the image. The problem here is that there are a number of possible formats for the header but the one that is used in most cases is the BitMapInfoHeader and its format is (Wikipedia):
Notice that the first field gives the size of the header and for the type of header we are expecting this should be 40. You need to add a check that it is 40 if there is any chance that you are going to encounter other types of BMP files. Next we have the size of the bit map and a bit later on the number of bits per pixel. In this case we are going to assume that it is 24 and that the pixels are stored in RGB format. BMP files do come in other forms including paletted and it is fairly easy to extend this example to deal with them. Notice that we are going to ignore the compression field as well - having to decompress the pixel data would take us into a completely different sort of problem.
Converting the raw bits into suitable fields follows the form of the previous header:
Finally all that is left is to transfer the pixel data. We already know where in the data starts - as its offset is stored in bfOffBits. To make the bits available all we have to do is associate the buffer with a Uint8Array leaving the program that makes use of the bitmap object to do any decoding needed to work with the pixels. An alternative scheme would be to unpack the data into three fields R, G and B. This would make the data easier to use but potentially slower.
The only other item of information that the bitmap object provides is the stride of the image. The image is stored one row at a time and if you know the number of bytes to a pixel you can work out the number of bytes in the row. The complication is that hardware likes the number of bytes in a row to be a multiple of 4 and so the number of bytes used to store a row sometimes isn't the same as the number of pixels times the bytes per pixel. The number of bytes used to store a row is usually called the stride - because its the number of bytes you have to step over to get the the next row. To make things easier the bitmap object calculates the stride for the user:
|Last Updated ( Tuesday, 27 August 2013 )|