CSC10002
BITMAP FILE TUTORIAL
FIT-HCMUS
Contents
1 Intoduction to Bitmap File Format 2
2 Structure of Bitmap File 2
2.1 File Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.1 Bitmap File Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.1.2 DIB Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.1.3 Pixel Data (Pixel Array) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3 Reading Bitmap File 5
3.1 Struct Bitmap Image in C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.2 Reading Bitmap File Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.3 Reading DIB (Info) Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3.4 Reading Pixel Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
4 Writing Bitmap File 6
5 References 7
1
Programming Techniques — 2021 Knowledge Engineering Department
1 Intoduction to Bitmap File Format
The Bitmap (BMP) file format is a raster graphics image file format used to store bitmap digital
images, especially on Microsoft Windows and OS/2 operating systems [1].
BMP files are commonly used for storing 2D digital images both monochrome and color. The
defautl BMP file is not a compressed image, has a fairly simple structure, is easier to read and edit
than other image formats.
This tutorial will focus on a 24-bit BMP file (with RGB color).
2 Structure of Bitmap File
2.1 File Structure
We can divide the BMP image structure into 3 main components as follows:
1. Header. The header component has smaller components:
• File header: Contains information about the size of the file and the offset of the pixel data.
• Info header (DIB header): Contains overview information about the image such as width,
height, size per pixel (number of colors),...
2. Color table: not important when reading or writing so it will not be covered in this tutorial.
3. Pixel data: Also known as bitmap data, pixel array; contains the RGB color information of the
pixels.
2.1.1 Bitmap File Header
Following is the table of contents of the Bitmap file header:
Field name Offset Size (bytes) Purpose
bfType 0 2 Used to identify the BMP file
bfSize 2 4 The size of the BMP file
bfReserved1 6 2 Not used, must be 0
bfReserved2 8 2 Not used, must be 0
bfOffBits 10 4 Offset, i.e. starting address, of the pixel data
Programming on Windows operating systems, we are supported with a full struct to read the
bitmap header data. We need to include the Windows.h library for support.
Page 2 / 7
Programming Techniques — 2021 Knowledge Engineering Department
2.1.2 DIB Header
Following is the table of contents of the Bitmap DIB header:
Field name Offset Size (bytes) Purpose
biSize 14 4 The size of this header
biWidth 18 4 The Bitmap width
biHeight 22 4 The Bitmap height
biPlanes 26 2 The number of color planes (must be 1)
biBitCount 28 2 The number of bits per pixel
bitCompression 30 4 The compression method being used
biSizeImage 34 4 The image size
biXPelsPerMeter 38 4 The horizontal resolution of the image
biYPelsPerMeter 42 4 The vertical resolution of the image
biClrUsed 46 4 The number of colors in the color palette, or 0 to default to 2n
biClrImportant 50 4 The number of important colors used; generally ignored
In programming, we use the struct BITMAPINFOHEADER available (in Windows.h).
2.1.3 Pixel Data (Pixel Array)
The pixel array is a block of 32-bit DWORDs, that describes the image pixel by pixel. Usually pixels
are stored “bottom-up”, starting in the lower left corner, going from left to right, and then
row by row from the bottom to the top of the image [2].
The BMP file stores order color according to the Little Endian rule. That means instead of saving
according to Red → Green → Blue, BMP stores to Blue → Green → Red.
There will be padding on each row in the BMP image when the total data per row is
not divisible by 4. Padding bytes (not necessarily 0) must be appended to the end of the rows in
order to bring up the length of the rows to a multiple of four bytes [1].
2.2 An Example
Following is an example of a 2 × 2 pixel, 24-bit Bitmap [1].
Page 3 / 7
Programming Techniques — 2021 Knowledge Engineering Department
Offset Size (bytes) Hex value Value Description
BMP Header
0 2 42 4D ”BM” ID field
2 4 46 00 00 00 70 bytes Size of the BMP file
6 2 00 00 Unused Application specific
8 2 00 00 Unused Application specific
10 4 36 00 00 00 54 bytes Offset where the pixel array can be found
DIB Header
14 4 28 00 00 00 40 bytes The size of this header
18 4 02 00 00 00 2 pixels (left to right order) The Bitmap width
22 4 02 00 00 00 2 pixels (bottom to top order) The Bitmap height
26 2 01 00 1 plane The number of color planes (must be 1)
28 2 18 00 24 bits The number of bits per pixel
30 4 00 00 00 00 0 The compression method being used (value = 0 → not compressed)
34 4 10 00 00 00 16 bytes The image size
38 4 13 0B 00 00 2835 pixels/metre horizontal The horizontal resolution of the image
42 4 13 0B 00 00 2835 pixels/metre vertical The vertical resolution of the image
46 4 00 00 00 00 0 colors The number of colors in the color palette, or 0 to default to 2n
50 4 00 00 00 00 0 important colors 0 means all colors are important
Pixel Array
54 3 00 00 FF 0 0 255 Red, Pixel (0, 1)
57 3 FF FF FF 255 255 255 White, Pixel (1, 1)
60 2 00 00 00 00 Padding for 4 byte alignment
62 3 FF 00 00 255 0 0 Blue, Pixel (0, 0)
65 3 00 FF 00 0 255 0 Green, Pixel (1, 0)
68 2 00 00 00 Padding for 4 byte alignment
Page 4 / 7
Programming Techniques — 2021 Knowledge Engineering Department
3 Reading Bitmap File
3.1 Struct Bitmap Image in C++
Declaration of struct Bitmap Image in C++:
1 struct Pixel
2 {
3 unsigned char blue;
4 unsigned char green;
5 unsigned char red;
6 };
7
9 struct BitmapImage
10 {
11 BITMAPFILEHEADER fileHeader; // #include <Windows.h>
12 BITMAPINFOHEADER infoHeader; // #include <Windows.h>
13
14 Pixel **data; // 2d array of pixels
15 int padding;
16 };
3.2 Reading Bitmap File Header
Function for reading the header using struct BITMAPFILEHEADER in Windows.h:
1 void ReadBitmapFileHeader(FILE *f, BITMAPFILEHEADER &bmpFileHeader)
2 {
3 int retCode = 0;
4 rewind(f);
5
6 retCode = fread(&bmpFileHeader, sizeof(bmpFileHeader), 1, f);
7 }
3.3 Reading DIB (Info) Header
Function for reading the header using struct BITMAPINFOHEADER in Windows.h:
1 void ReadBitmapInfoHeader(FILE *f, BITMAPINFOHEADER &bmpInfoHeader)
2 {
3 int retCode = 0;
4 fseek(f, 0xE, SEEK_SET); // 0xE = 14, DIB starts from offset 14
5
6 retCode = fread(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, f);
7 }
Page 5 / 7
Programming Techniques — 2021 Knowledge Engineering Department
3.4 Reading Pixel Array
This tutorial provides only program framework that helps you to read pixel array without imple-
menting.
1 BitmapImage bmpImage;
2
3 // Read Bitmap File Header
4 ReadBitmapFileHeader(fileName, bmpImage.fileHeader);
5 // Read Bitmap (DIB) Info Header
6 ReadBitmapInfoHeader(fileName, bmpImage.infoHeader);
7
8 // Check if biBitCount is 24, reutrn error if != 24
9
10 // Check if the image is compressed, return error if != 0
11
12 // Get the height and width of the image from infoHeader
13
14 // Memory allocation for Pixel Array (2d array with the number of rows is height, the number of columns is
width.
15
16 // Find the number of padding bytes and assign to bmpImage.padding.
17 // Hint: padding = 4 - (total number of bytes per row mod 4). If padding = 4 --> update padding = 0
18
19 // Seek file into bfOffBits (starting of the pixel data) using:
20 fseek(fileName, bmpImage.fileHeader.bfOffBits, SEEK_SET);
21
22 // Loop from (height - 1) to 0 (row by row from the bottom to the top of the image):
23 // Read each rows of image into Pixel Array using:
24 fread(bmpImage.data[i], 3, width, fileName);
25
26 // Remember to ignore padding for each rows IF padding != 0, using:
27 fseek(fileName, padding, SEEK_CUR))
4 Writing Bitmap File
Function for writing a Bitmap file:
1 void WriteBitmapFile(FILE *f, const BitmapImage &bmpImage)
2 {
3 int retCode = 0;
4 char tmp[3] = { 0 }; // pixel for padding
5
6 rewind(f);
7
8 // Writing header
9 retCode = fwrite(&bmpImage.fileHeader, sizeof(BITMAPFILEHEADER), 1, f);
10 retCode = fwrite(&bmpImage.infoHeader, sizeof(BITMAPINFOHEADER), 1, f);
11
12
Page 6 / 7
Programming Techniques — 2021 Knowledge Engineering Department
13 // Padding to pixel array data
14 while (ftell(f) < bmpImage.fileHeader.bfOffBits)
15 fwrite(tmp, 1, 1, f);
16
17
18 int height = bmpImage.infoHeader.biHeight;
19 int width = bmpImage.infoHeader.biWidth;
20
21 for (int i = height - 1; i >= 0; i--)
22 {
23 fwrite(bmpImage.data[i], 3, width, f);
24
25 // Padding
26 if (bmpImage.padding != 0)
27 fwrite(tmp, 1, bmpImage.padding, f);
28 }
29 }
5 References
References
[1] Bitmap file format, https://en.wikipedia.org/wiki/BMP_file_format
[2] “DIBs and Their Uses”, Microsoft Help and Support, Retrieved 2015-05-14.
—— END ——
Page 7 / 7