Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

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

You might also like