Detailed descriptions of BMP file operations by goodoo

Source: Internet
Author: User
Tags bmp image scale image

1. BMP file structure and its access
Digital images are stored on external storage devices in the form of image files. images must be stored in a known and accepted data storage sequence and structure, in this way, different programs can smoothly open or store image files to achieve data sharing. The storage sequence and structure of image data in files are called image file formats. There are many popular formats of image files, including BMP, GIF, JPEG, Tiff, PSD, DICOM, and MPEG. Among the various image file formats, some are the formats proposed and widely accepted and adopted by a software or hardware vendor, such as BMP, GIF, and PSD; another part is the formats proposed by various international standards organizations, such as JPEG, Tiff, and DICOM. JPEG is the format proposed by the International Standards Organization for static image compression, tiff is a format proposed by some manufacturers and DICOM is a specialized format for medical images proposed by the International Medical Image standards organization.
BMP files are recommended and supported image file formats in the Windows operating system. It is a file format that stores the image data of the memory or display in a bits without being compressed, therefore, it is called a bitmap file. Because its file extension is BMP, it is called a BMP file format, or BMP file for short. The Algorithm Programming of images in this book is aimed at BMP image files. Therefore, we will introduce the structure of BMP files and Their read/write operations in detail in this chapter to deepen our understanding of image data.
1.1 BMP file structure
As shown in figure 1-7, BMP image files are divided into four parts: bitmap file header, bitmap info header, and color map) and bitmap data (that is, image data, data bits, or data body ).
Part 1 is the bitmapfileheader of the bitmap file header, which is a struct type and has a fixed length of 14 bytes. It is defined as follows:
Typedef struct tagbitmapfileheader
{
Word bftype;
DWORD bfsize;
Word bfreserved1;
Word bfreserved2;
DWORD bfoffbits;
} Bitmapfileheader, far * lpbitmapfileheader, * pbitmapfileheader;
The fields of the bitmapfileheader structure are described as follows:
-Bftype: the type of the bitmap file. It must be 0x0000d, that is, the string "BM". That is, the first two bytes of all "*. BMP" files are "BM ".
-Bfsize: the size of the bitmap file, including the 14 bytes.
-Bfreserved1 and bfreserved2: Reserved Words for Windows.
-Bfoffbits: the number of offset bytes from the file header to the actual bitmap data. The sum of the lengths of the first three parts in Figure 1-7.
Part 1 is the bitmapinfoheader, which is also a Data Structure of the struct type. The length of this structure is also fixed and is 40 bytes (word is a 16-bit integer without symbols, DWORD is an unsigned 32-bit integer, and long is a 32-bit integer ). It is defined as follows:
Typedef struct tagbitmapinfoheader
{
DWORD bisize;
Long biwidth;
Long biheight;
Word biplanes;
Word ititcount
DWORD bicompression;
DWORD bisizeimage;
Long bixpelspermeter;
Long biypelspermeter;
DWORD biclrused;
DWORD biclrimportant;
} Bitmapinfoheader, far * lpbitmapinfoheader, * pbitmapinfoheader;
The fields of the bitmapinfoheader structure are described as follows:
-Bisize: the length of this structure, 40 bytes.
-Biwidth: the bitmap width, in pixels.
-Biheight: the height of the bitmap, in pixels.
-Biplanes: the level of the target device, which must be 1.
-Bibitcount: The number of BITs occupied by each pixel. The values must be 1 (black and white image), 4 (16-color image), 8 (256 colors), and 24 (true color image ), the new BMP format supports 32-bit colors.
-Bicompresssion: bitmap compression type. Valid values include bi_rgb (uncompressed), bi_rle8, bi_rle4, and bi_bitfileds (Windows-defined constants ). Here we only discuss uncompress, that is, bicompression = bi_rgb.
-Bisizeimage: the number of bytes occupied by the actual bitmap data. The size of this value is explained in Part 1 of the bitmap data.
-Bixpelspermeter: Specifies the horizontal resolution of the target device, in pixels/meters.
-Biypelspermeter: Specifies the vertical resolution of the target device, in pixels/meters.
-Biclrused: the number of colors actually used by the bitmap. If the value is zero, the bitmap uses the bibitcount power of 2.
-Biclrimportant: number of important colors in the bitmap display process. If the value is zero, all colors are considered important.
Part 1 is the color table. The color table is actually an array of the rgbquad structure. The length of the array is specified by biclrused (if the value is zero, it is specified by bibitcount, that is, the bibitcount sub-power element of 2 ). The rgbquad structure is a struct type, which occupies 4 bytes. Its definition is as follows:
Typedef struct tagrgbquad
{
Byte rgbblue;
Byte rgbgreen;
Byte rgbred;
Byte rgbreserved;
} Rgbquad;
The fields of the rgbquad structure are described as follows:
-Rgbblue: the blue component of the color;
-Rgbgreen: the green component of the color;
-Rgbred: The Red weight of the color;
-Rgbreserved: Reserved bytes, not used at the moment.
Some bitmaps require a color table. Some bitmaps (such as a true color chart) do not require a color table. The length of the color table is determined by the bibitcount component in the bitmapinfoheader structure. For binary images with a bibitcount value of 1, each pixel occupies 1 bit. There are only two colors (such as black and white) in the image, and the color table has 21 = two table items, the size of the entire color table is one byte. for Grayscale Images with 8 ititcount values, each pixel occupies 8 bits. The image contains 28 = 256 colors, and the color table contains 256 Items, the R, G, and B components of each table item are equal. The size of the entire color table is in bytes, because the three bytes in each pixel represent the R, G, and B values respectively, the color table is not required. Therefore, bitmapinfoheader structure of a true color chart is followed by bitmapinfoheader data.
Part 1 is bitmap data, that is, image data. It records each pixel value of the image immediately following the bitmap file header, bitmap information header, and color table (if there is a color table. For bitmap with a color table, the bitmap data is the index value of the pixel color in the color palette. For a true color chart, bitmap data is the actual R, G, and B values (the storage sequence of the three components is B, G, and R ). The following describes the bitmap data of two-color, 16-color, 256-color, and true-color bitmap:
-For a two-color bitmap, one digit can represent the color of the pixel. Therefore, one word saves 8 pixel color values.
-For a 16-color bitmap, four digits can represent the color of a pixel. Therefore, one byte can store two pixel color values.
-For a 256-color bitmap, one byte stores the color value of one pixel.
-For a true color bitmap, three bytes can represent the color value of one pixel.
Pay attention to the following two points:
First, Windows requires that the number of bytes occupied by a row to be scanned must be a multiple of 4. If the number is less than a multiple of 4, it must be expanded. Assume that the image width is biwidth pixels and each pixel is biitcount bits. The formula for calculating the actual bytes occupied by one scanned row is as follows:
Datasizeperline = (biwidth * bibitcount/8 + 3)/4*4
In this case, the bitmap data size (the bisizeimage member in the bitmapinfoheader structure) is calculated as follows:
Bisizeimage = datasizeperline * biheight
Second, in general, the data in the BMP file is scanned from the lower left corner of the image, that is, the pixel values of the image are recorded one by one from bottom to top, from left to right, therefore, the zero point of the image coordinate is in the lower left corner of the image.
1.2.2 read/write BMP image files
After analyzing the BMP file structure, we can use a simple C program to read and write a given BMP bitmap file to further consolidate our understanding of image data, this is also the basis for subsequent visual image programming. This part of the code and the code described in the next two sections are in the BMP readwrite. cpp file in the project chap1-1, readers can refer.
1. Read BMP files
BMP files are divided into four components. Therefore, the reading of BMP files must be processed in order according to the four components. That is, the bitmapfileheader structure is processed first, followed by the bitmapinfoheader structure and color table, the last part is bitmap data.
First, definitions of bitmapfileheader, bitmapinfoheader, rgbquad, and other structures are included in the header file windows. h.
# Include "windows. H"
Next, we define several global variables to store the bitmap data, width, height, color table, and number of digits per pixel that are read into the image. The global variables are defined as follows:
Unsigned char * pbmpbuf; // pointer for reading image data
Int BMP width; // The image width.
Int bmpheight; // Image Height
Rgbquad * pcolortable; // color table pointer
Int bibitcount; // image type, number of digits per pixel
According to the BMP file structure, the basic process for reading a BMP file is 1-8.
The readbmp () function allows you to read BMP files. The following code describes and implements the readbmp () function.
/*************************************** ********************************
* Function Name:
* Readbmp ()
*
* Function parameters:
* Char * BMP name-file name and Path
*
* Return value:
* 0 indicates failure, and 1 indicates success.
*
* Description: given an image file name and path, read the bitmap data, width, height, and color table of the image and each pixel.
* Data such as digits are stored in the memory and stored in the corresponding global variables.
**************************************** *******************************/
Bool readbmp (char * BMP name)
{
// Open the specified image file in binary read mode
File * fp = fopen (BMP name, "rb ");
If (FP = 0) return 0;
// Skip bitmapfileheader
Fseek (FP, sizeof (bitmapfileheader), 0 );
// Define the bitmap information header structure variable, read the bitmap information header into the memory, and store it in the variable head
Bitmapinfoheader head;
Fread (& head, sizeof (bitmapinfoheader), 1, FP );
// Obtain the image width, height, and number of digits per pixel.
BMP width = head. biwidth;
Bmpheight = head. biheight;
Bibitcount = head. bibitcount;
// Define the variable to calculate the number of bytes occupied by each pixel in the image (must be a multiple of 4)
Int linebyte = (BMP width * bibitcount/8 + 3)/4*4;
// Grayscale images have a color table, and the color table item is 256
If (bibitcount = 8 ){
// Apply for the space required by the color table. Read the color table into the memory.
Pcolortable = new rgbquad [256];
Fread (pcolortable, sizeof (rgbquad), 256, FP );
}
// The space required to apply for bitmap data. Read bitmap data into the memory.
Pbmpbuf = new unsigned char [linebyte * bmpheight];
Fread (pbmpbuf, 1, linebyte * bmpheight, FP );
// Close the file
Fclose (FP );
Return 1;
}
2. Storage of BMP files
Given the image path name and image data, the write operation on the image is also performed according to the four components of the BMP file. The basic process is 1-9.
The savebmp () function implements write operations on BMP files. The description and code of this function are as follows.
/*************************************** **
* Function Name:
* Savebmp ()
*
* Function parameters:
* Char * BMP name-file name and Path
* Unsigned char * imgbuf-bitmap data of the disk to be saved
* Int width-the width of the bitmap to be stored in pixels
* Int height-the height of the bitmap to be stored in pixels
* Int bibitcount-number of digits per pixel
* Rgbquad * pcolortable-color table pointer
* Return value:
* 0 indicates failure, and 1 indicates success.
*
* Note: Given the bitmap data, width, height, and color table pointer of an image and the number of digits occupied by each pixel,
* Write it to the specified file
**************************************** *******************************/
Bool savebmp (char * BMP name, unsigned char * imgbuf, int width, int height,
Int bibitcount, rgbquad * pcolortable)
{
// If the bitmap data pointer is 0, no data is passed in and the function returns
If (! Imgbuf)
Return 0;
// The color table size, in bytes. The gray scale image color table is 1024 bytes, and the color image color table size is 0.
Int colortablesize = 0;
If (bibitcount = 8)
Colortablesize = 1024;
// The number of bytes in each row of the image data to be stored is a multiple of 4.
Int linebyte = (width * bibitcount/8 + 3)/4*4;
// Open the file in binary mode
File * fp = fopen (BMP name, "WB ");
If (FP = 0) return 0;
// Apply for bitmap file header Structure Variables and fill in the file header information
Bitmapfileheader filehead;
Filehead. bftype = 0x4d42; // BMP Type
// Bfsize is the sum of the four components of an image file.
Filehead. bfsize = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader)
+ Colortablesize + linebyte * height;
Filehead. bfreserved1 = 0;
Filehead. bfreserved2 = 0;
// Bfoffbits is the sum of the space required for the first three parts of the image file.
Filehead. bfoffbits = 54 + colortablesize;
// Write the file header into the file
Fwrite (& filehead, sizeof (bitmapfileheader), 1, FP );
// Apply for bitmap information header Structure Variables and fill in information header information
Bitmapinfoheader head;
Head. bibitcount = bibitcount;
Head. biclrimportant = 0;
Head. biclrused = 0;
Head. bicompression = 0;
Head. biheight = height;
Head. biplanes = 1;
Head. bisize = 40;
Head. bisizeimage = linebyte * height;
Head. biwidth = width;
Head. bixpelspermeter = 0;
Head. biypelspermeter = 0;
// Write bitmap information header into memory
Fwrite (& head, sizeof (bitmapinfoheader), 1, FP );
// If the grayscale image has a color table, write it to a file
If (bibitcount = 8)
Fwrite (pcolortable, sizeof (rgbquad), 256, FP );
// Write bitmap data into the file
Fwrite (imgbuf, height * linebyte, 1, FP );
// Close the file
Fclose (FP );
Return 1;
}
A simple call to readbmp () and savebmp () functions is as follows:
Void main ()
{
// Read the specified BMP file into the memory
Char readpath [] = "dog. BMP ";
Readbmp (readpath );
// Output image information
Printf ("width = % d, Height = % d, bibitcount = % d/N", BMP width, bmpheight, bibitcount );
// Save image data to disk
Char writepath [] = "dogcpy. BMP ";
Savebmp (writepath, pbmpbuf, BMP width, bmpheight, bibitcount, pcolortable );
// Clear the buffer. pbmpbuf and pcolortable are global variables. The space applied for when the file is read
Delete [] pbmpbuf;
If (bibitcount = 8)
Delete [] pcolortable;
}
The main () function reads the specified BMP file into the memory, prints the image information, and stores it in the specified file as is. The reader can download the dog.bmp and mongodogcpy.bmp files under the project to compare them.
The preceding read/write functions for BMP files are only applicable to grayscale images (bibitcount = 8) and color images (bibitcount = 24). For other image types such as bibitcount = 1, you can simply modify the program as needed. The subsequent code implementation in this book is also based on the gray and color formats. I hope you will pay attention to it.
1.2.3 access to BMP image bitmap data
The above main () function reads the image file into the memory and writes it to the file. Then, after reading the image data and writing it to the file, image data exists in the memory, which is also the time when we can modify (ACCESS) image data.
Assume that the pointer to the bitmap data in the memory is pbmpbuf, and the number of bytes occupied by a row of pixels is a multiple of linebyte (4, the pixel pointer (location of the bucket) in column J of row I is pbmpbuf + I * linebyte + J, * (pbmpbuf + I * linebyte + J) is the gray value of the pixel. To change the pixel to a specified color, you only need to assign the specified value to * (pbmpbuf + I * linebyte + J). For color images, each pixel occupies 3 bytes, then pbmpbuf + I * linebyte + J * 3 + 0, pbmpbuf + I * linebyte + J * 3 + 1, pbmpbuf + I * linebyte + J * 3 + 2 represent pointer of three parts of the J column pixel B, G, and R in the I line, if you want to specify a color for the point, you need to assign values to the three components respectively.
In the following main () function, set the first part of the image data in the lower left corner to black and save the data. Figure 1-10 shows the changes of the image before and after the program runs.
Void main ()
{
// Read the specified BMP file into the memory
Char readpath [] = "dog. BMP ";
Readbmp (readpath );
// Output image information
Printf ("width = % d, Height = % d, bibitcount = % d/N", BMP width, bmpheight, bibitcount );
// Cycle variable, image coordinate
Int I, J;
// Number of bytes per line
Int linebyte = (BMP width * bibitcount/8 + 3)/4*4;
// Cyclic variable. For color images, traverse the three components per pixel
Int K;
// Black the first part in the lower left corner of the image
If (bibitcount = 8) {// for Grayscale Images
For (I = 0; I For (j = 0; j * (Pbmpbuf + I * linebyte + J) = 0;
}
}
}
Else if (bibitcount = 24) {// Color Image
For (I = 0; I For (j = 0; j For (k = 0; K * (pbmpbuf + I * linebyte + J * 3 + k) = 0;
}
}
}
// Save image data to disk
Char writepath [] = "dogcpy. BMP ";
Savebmp (writepath, pbmpbuf, BMP width, bmpheight, bibitcount, pcolortable );
// Clear the buffer. pbmpbuf and pcolortable are global variables. The space applied for when the file is read
Delete [] pbmpbuf;
If (bibitcount = 8)
Delete [] pcolortable;
}
Figure 1-10 image comparison after data modification
1.2.4 grayscale image color table
As shown in table 1-2, the color table of the grayscale image is an array of the rgbquad struct of 256 table items (see the description of the color table in the BMP file structure ), the R, G, and B values in each rgbquad are equal. As the subscript of the array changes from 0 to 255, the R, G, and B components of the array elements also change from 0 to 255. The bitmap data of a grayscale image is one byte per pixel and the value ranges from 0 to 255. When a grayscale image is displayed, view the color in the table item (array element) corresponding to the subscript of the color table array, and display pixels according to the color in the table item. Since the R, G, and B Components in each table of the gray-scale image color table are equal, only the image brightness information and color information are available. Therefore, the displayed gray-scale image has no color.
Table 1-2 colors of grayscale images
B
G
R
Reservation
0
0
0
Uncertain
1
1
1
Uncertain
2
2
2
Uncertain
3
3
3
Uncertain
M
M
M
M
254
254
254
Uncertain
255
255
255
Uncertain
From the above explanation, we know that the image color table determines the color of the image. If the color table data of the gray image is changed, the color of the image will naturally be changed. The following main () function changes the blue component of the grayscale image color table.
Void main ()
{
// Read the specified BMP file into the memory
Char readpath [] = "dog. BMP ";
Readbmp (readpath );
// Output image information
Printf ("width = % d, Height = % d, bibitcount = % d/N", BMP width, bmpheight, bibitcount );
// Change the value of the blue component of the grayscale image, and view the changes before and after
If (bibitcount = 8 ){
For (INT I = 0; I pcolortable [I]. rgbblue = 255-pcolortable [I]. rgbblue;
}
}
// Save image data to disk
Char writepath [] = "dogcpy. BMP ";
Savebmp (writepath, pbmpbuf, BMP width, bmpheight, bibitcount, pcolortable );
// Clear the buffer. pbmpbuf and pcolortable are global variables. The space applied for when the file is read
Delete [] pbmpbuf;
If (bibitcount = 8)
Delete [] pcolortable;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.