This tutorial aims to quickly teach you how to right your ANSI C code to add 2
images. Adding two images is important because it allows you to modify an image
that is projected, say, on a whiteboard by adding the information drawn on that
white board assuming you used Mimio to capture
the information drawn on top of your projected image. Furthermore bmp processing
is the first step to learn image processing for machine vision.
The rest of the tutorial is presented as follows:
Bit-Mapped Graphic Files
A bitmap is an array of bits that specifies the color of each pixel in a rectangular array of pixels. The number of bits devoted to an individual pixel determines the number of colors that can be assigned to that pixel. For example, if each pixel is represented by 8 bits, then a given pixel can be assigned 256 different colors (2^8 = 256). Disk files that store bitmaps usually contains one or more information blocks that store information such as number of bits per pixel, number of pixels in each row, and number of rows in the array. Such a file might also contain a color table (sometimes called a color palette). A color table maps numbers in the bitmap to specific colors. For example an 8-bit BMP file would have a color table that matches 256 colors to 3 byte RGB values of the colors, whereas a 24-bit BMP file does not have a color table.
Let's have a look into a BMP files inside. Following table shows the format of a BMP file.
Table 1. BMP File Format.
|
NAME |
SIZE |
POS. |
DESCRIPTION |
|
HEADER |
14 BYTES TOTAL |
||
|
Signature |
2 bytes |
0-1 |
BM |
|
File Size |
4 bytes |
2-5 |
File Size in Bytes |
|
Reserved 1 |
2 bytes |
6-7 |
Unused (=0) |
| Reserved 2 | 2 bytes | 8-9 | Unused (=0) |
| Data Offset | 4 bytes | 10-13 | Offset Value to Raster Data |
| INFO HEADER | 40 BYTES TOTAL | ||
| Size | 4 bytes | 14-17 | Size of Info Header (=40) |
| Width | 4 bytes | 18-21 | Image Width in Pixels |
| Height | 4 bytes | 22-25 | Image Height in Pixels |
| Planes | 2 bytes | 26-27 | Number of Planes (=1) |
| Bit Count | 2 bytes | 28-29 | Bits per Pixel (1, 4, 8 ,16, 24) |
| Compression | 4 bytes | 30-33 |
Type of Compression 0 = No compression 1 = 8-bit RLE encoding 2 = 4-bit RLE encoding |
| Image Size | 4 bytes | 34-37 |
(Compressed) Image Size |
| X Pixels per Meter | 4 bytes | 38-41 | Horizontal Resolution pixels/m |
| Y Pixels per Meter | 4 bytes | 42-45 | Vertical Resolution pixels/m |
| Colors Used | 4 bytes | 46-49 | Number of Actual Colors Used (0 = 24-bit) |
| Colors Important | 4 bytes | 50-53 | Number of Important Colors (=0 is all) |
In Table 1, it can be observed that first 54 bytes of a BMP is used to describe the image file. Next, there might be a color table (There will probably be a color table if the bit count is less than or equal to 8 bits.) For 8-bit images there is a color table and its size is 1024 ( = (2^3)*4 ) bytes. Therefore from byte # 54 to 1023 of 8-bit images there is the color table. Then starting at byte # 1078 of 8-bit images ( = 14 + 40 + 1024), there is the raster data. Raster data is composed of the corresponding color value of each pixel. Therefore raster data is width*height long for 8-bit BMP files. For 24-bit images there is no color table and raster data starts right at byte # 54. Raster data of a 24-bit BMP is composed of RGB value of each pixel in 3-byte stacks. First byte is the blue value of the color ( = 0 - 255), second byte is the green value of the color (= 0 - 255) and the last byte is red value of the color (= 0 - 255). Note that numbers from 0 to 255 can be stored in a byte, or as unsigned character.
Reading The Header of a BMP
To be compiled with
Turbo C
Note: download header.c rather than cutting
and pasting from below.
Explanation of Header.c:
Header.c first opens the bmp file that is input to the main of the code and then retrieves the header information of a bmp file using the function getImageInfo. The format of a bmp file is given in Table 1. getImageInfo winds the bmp file to the relevant byte to read the required data and reads the required data byte by byte to obtain the value of the required data. Note that fseek function is used to wind the bmp file. As an example consider retrieving the width of the bmp. The width of the bmp is stored at bytes # 18-21. Therefore getImageInfo first rewinds the bmp file to byte # 18. Then reads 4 bytes of data byte by byte to find the 4-byte value of the width of the bmp. Instead of reading byte by byte you could also read 4-byte by 4-byte by using a long integer type variable for reading the bmp file. However, for there are some information stored in only 2-bytes that would require us to have two functions; one that reads 2 byte information and the other that reads 4-byte information.
|
/* Read a Bitmap File */ { {
/* Read BMP input file */ |
Combining Two 8-bit grayscale BMPs
To be compiled with
Turbo C
Note: download bmpadd3.c rather than cutting
and pasting from below.
|
/* First it copies the first BMP's header, color table to the output BMP file, which is going to be the combination of the two images. Then whenever there is a color information other than white (255) in the second file that information is copied to the output file. Therefore it is supposed that white is the unnecessary information in the second file. Furthermore this code needs to have same sized bmp files to accomplish the addition. Because every bmp that has a color table would have different color tables, only grayscale addition is possible with bmp files having color tables (bmp files that are 8-bit and lower). Grayscale 8-bit images has the same color table, 256 shades of gray. */ printf("Height of File 1: \t%d\n",
r1); printf("Bits/pixel of File 1:
\t%ld\n", nbits1);
/* Copy the non-white of image 2 to output */ |
Example: Below pictures illustrate the addition of two 8-bit grayscale images.
Combining Two 24-bit BMPs
To be compiled with
Turbo C
Note: You can download bmp24ad3.c.
It is quite similar to 8-bit version. The only difference is in the bmp processing part of the algorithm. In 24-bit images every pixel has a RGB value as mentioned before in the beginning of this tutorial.
| /* COMBINE TWO 24-BIT IMAGES */ ..... .... /*/////////////////////////*/ } .... .... |
Example: Below pictures illustrate the addition of two 24-bmp images.
This tutorial's objective was to show how to add two images by using ANSI C.
Click here to email me