Windows bitmap and palette

Source: Internet
Author: User
Tags bmp image

Guidance:
Windows bitmap and palette)
1. Concepts of Bitmap and palette
Nowadays, Windows (3.x and 95, NT) series have become the operating systems used by most users. It is more efficient
An important factor in success is its visual beautiful interface. For example, you can add your favorite wallpaper on the desktop. That
How does one display images in windows? This involves bitmap ).
We know that a normal display screen is composed of many points, which are called pixels. Used for display
Scan Method: the electron gun scans a row from left to right, coloring each pixel, and scanning from top to bottom.
After several rows, the screen is scanned. To prevent flickering, repeat the above process dozens of times per second. For example
The screen resolution is 640*480, And the refresh frequency is 70Hz. This means that each line needs to scan 640 pixels, a total of 480 rows.
, Scan the screen 70 times per second. We call this monitor a bit image device. A Bitmap refers to
A two-dimensional Pixel matrix, while a bitmap is used to display and store images. For example, 1 is
A normal black/white bitmap. Figure 2 is the enlarged image. Each square in the figure represents a pixel. We can see that
: The entire skeleton is composed of such black points and white points.
  
Figure 1. Skeleton (left) Figure 2. Enlarged skeleton Bitmap (right)
So what is the color chart?
Let's talk about the three-element RGB concept. We know that all colors in nature can be red, green, blue (R
, G, B. Some colors contain more red components, such as dark red; some contain less red components.
, Such as light red. The number of groups containing red ingredients can be divided into 0 to 255 and a total of 256 levels. The value 0 indicates that the value does not contain red.
Level 255 indicates that the product contains 100% of the red ingredients. Similarly, green and blue are also divided into 256 levels. This hierarchical
The concept is called quantization. In this way, different combinations of red, green, and blue indicate 256*256*256,
About 1 million 6 million colors. So many colors are enough for our human eyes.
The following table lists the RGB values of some common colors.
Color r g B
Red 255 0 0
Blue 0 0 255
Green 0 255 0
Yellow 255 255 0
Purple 255 0 255
Qing0 255 255
White 255 255 255
Black 0 0 0
Gray 128 128 128
As you may have understood, when each pixel in a graph has a different RGB value, it will be colorful.
In this way, a color chart is formed. Yes, but there are still some differences in practice.
Let's take a look at the example below.
There is a color map with a length and width of 200 pixels and 16 colors. Each pixel uses three components: R, G, and B.
Because each component has 256 levels, it must be expressed in 8 bits, that is, one byte.
Each pixel must contain three bytes. The entire image should be 200*200*3, about KB, not a small number.
! If we use the following method, we can save a lot of effort. Because it is a 16-color graph, that is, this graph can only
There are 16 colors. We can use a table: each row in the table records the R, G, and B values of a color. In this way, when we
To indicate the color of a pixel, you only need to specify the number of rows of the color, that is, the index value of the color in the table. Example
Example: If the table's 0th behavior is, 0, 0 (red), when a pixel is red, you only need to indicate
0. Let's calculate it again: 16 states can be expressed in 4 bits, so a pixel needs to be half
Bytes. The entire image should contain 200*200*0.5, about 20 K bytes, plus 3*16 = 48 bytes in the preceding table.
The total number of bytes occupied is about 1/6.
This RGB table is also called the color palette (palette). Another name is the color lookup table LUT (Lookup
Table. In Windows bitmap, the color palette technology is used.
Images, many image file formats such as PCX, Tif, and GIF are used. So the concept of a good understanding of the color palette is ten
Important.
There is a graph with a color number of up to 256*256*256, that is, including the R, G, and B colors we mentioned above.
Indicates all colors in the method. This image is called a truecolor ). A true color chart does not mean a graph package.
All colors are included, but they are capable of displaying all colors, that is, they can contain at most all colors. Table
When displaying a true color chart, each pixel is represented by three sub-bytes, namely R, G, and B, instead of the color palette.
Obviously: If a color palette is used, 24 bits are used to indicate a pixel. This is because each color index uses 24 bits.
(Because there is a total of two 24 Power colors, that is, the color palette has two 24 square lines), and directly use the R, G, B three components
It indicates that the same number of bytes is used, not only is there no cheap, but also adds a large color of 256*256*256*3 bytes.
Board. Therefore, a true color chart is represented by three components: R, G, and B. It is also called a 24-bit color chart.
2. BMP file format
Introduce the concept of the Location Map and the color palette. Next, let's take a look at the windows map file (.bmp ).
Format. The BMP file is roughly divided into four parts, as shown in 3.
Figure 3. Windows bitmap file structure (right)
The first part is bitmapfileheader, a structure, which is defined as follows:
Typedefstructtagbitmapfileheader {
Word bftype;
DWORD bfsize;
Word bfreserved1;
Word bfreserved2;
DWORD bfoffbits;
} Bitmapfileheader;
The length of this structure is fixed and 14 bytes (word is a 16-bit integer without symbols, DWORD is a 32-bit integer without symbols)
Number), the description of each domain is as follows:
Bftype
Specifies the file type, which must be 0x0000d, that is, the string "BM". Also, the header two bytes of all. BMP files are
Yes "BM"
Bfsize
Specify the file size, including the 14 bytes
Bfreserved1, bfreserved2
Reserved Words, no need to consider
Bfoffbits
It is the number of offset bytes from the file header to the actual bitmap data, that is, the sum of the length of the first three parts in figure 3.
The second part is bitmapinfoheader, which is also a structure. Its definition is as follows:
Typedef struct tagbitmapinfoheader {
DWORD bisize;
Long biwidth;
Long biheight;
Word biplanes;
Word bibitcount;
DWORD bicompression;
DWORD bisizeimage;
Long bixpelspermeter;
Long biypelspermeter;
DWORD biclrused;
DWORD biclrimportant;
} Bitmapinfoheader; the length of this structure is fixed to 40 bytes (Word is an unsigned 16-bit integer
, DWORD unsigned 32-bit integer, long is a 32-bit integer), the description of each domain is as follows:
Bisize
Specify the length of this structure, which is 40
Biwidth
Specify the image width in pixels.
Biheight
Specifies the Image Height, in pixels.
Biplanes
It must be 1.
Bibitcount
Specify the number of digits to be used when the color is used. The common values are 1 (black and white two-color chart), 4 (16 color chart), and 8 (256 color)
, 24(true color graph (the new. BMP format supports 32-bit colors, which will not be discussed here ).
Bicompression
Whether the bitmap is compressed. Valid values include bi_rgb, bi_rle8, bi_rle4, and bi_bitfields.
Windows defined constants ). It should be noted that the Windows bitmap can adopt the rle4 and rle8 compression formats.
But not much. We will discuss only the first case of no compression, that is, bicompression is bi_rg.
B.
Bisizeimage
The number of bytes occupied by the actual bitmap data can also be calculated from the following formula:
Bisizeimage = biwidth' * biheight
Note that the biwidth' in the above formula must be an integer multiple of 4 (so it is not biwidth, but biwidt
H ', indicating the integer multiple closest to 4, which is greater than or equal to biwidth. For example, if biwidth = 240, B
Iwidth' = 240; If biwidth = 241, biwidth' = 244) If bicompression is bi_rgb, this item
Possible 0
Bixpelspermeter
Specify the horizontal resolution of the target device. The unit is the number of pixels per meter.
The printed part is described in detail.
Biypelspermeter
Specifies the vertical resolution of the target device, in the same unit as above.
Biclrused
Specify the number of colors actually used by the image. If the value is zero, the number of colors used is 2 to the power of ititcount.
Biclrimportant
Specify the number of important colors in the image. If the value is zero, all colors are considered important.
The third part is the palette. Of course, this is for bitmap files that require the palette. Some
Bitmap, such as a true color chart, as mentioned earlier, does not require a color palette. bitmapinfoheader is directly followed by a bit.
Graph data.
The color palette is actually an array with a total of biclrused elements (if this value is zero, there will be 2 bibitcount
Power element ). The type of each element in the array is an rgbquad structure, which occupies 4 bytes. Its definition is as follows:
Typedef struct tagrgbquad {
Byte rgbblue; // The Blue weight of the color.
Byte rgbgreen; // The green weight of the color.
Byte rgbred; // The Red weight of the color.
Byte rgbreserved; // reserved value
} Rgbquad;
The fourth part is the actual image data. For bitmap that uses the color palette, the image data is the pixel face
The index value in the color palette. For a true color chart, the image data is the actual R, G, and B values. There are 2 colors, 16 colors, and 25 below.
6-color bitmap and true-color bitmap are introduced respectively.
For a two-color bitmap, the color of the pixel can be expressed with 1 bit (generally 0 indicates black, 1 indicates white), so a word
It can represent 8 pixels.
For a 16-color bitmap, four digits can represent the color of one pixel, so one byte can represent two pixels.
For a 256-color bitmap, one byte can represent exactly one pixel.
For a true color chart, three bytes can represent 1 pixel.
Pay attention to the following two points:
1. The number of bytes in each row must be an integral multiple of 4. If not, you need to complete it. This section describes the bisizeim
Age.
2. In general, the data in the. BMP file is from bottom to top, left to right. That is to say, the first read in a file
Is the first pixel on the left of the bottom line of the image, then the second pixel on the left... Next is the last and second rows left.
The first pixel on the side, the second pixel on the left... And so on. The final result is the rightmost pixel of the top row.
.
Okay, I finally finished introducing the BMP file structure. Do you think the header is too big? Don't worry, compare with the following program,
You will be very clear.
3. display the C program of a BMP file
The function of loadbmp is to read data from A. BMP file (including bitmapinfoheade
R, color palette and actual image data) store it in a global memory handle himgdata.
It is used in future image processing programs. At the same time, fill in a global variable hbitmap of the hbitmap type and
The global variable hpalette of the hpalette type. These two variables are used to process the wm_paint message.
The output chart is displayed. The two parameters of the map are used to display the window periods of the map, and the. BMP file name (full path ).
If the function is successful, true is returned. Otherwise, false is returned.
Bitmapfileheader BF;
Bitmapinfoheader Bi;
Bool loadbmp file (hwnd, char * BMP filename)
{
Hfile Hf; // file handle
Lpbitmapinfoheader lpimgdata; // pointer to the bitmapinfoheader Structure
Logpalette * ppal; // pointer to the logical palette Structure
Lprgbquad lprgb; // pointer to the rgbquad Structure
Hpalette hprevpalette; // used to save the original palette in the device
HDC; // device handle
Hlocal hpal; // stores the local memory handle of the palette.
DWORD linebytes; // The number of bytes in each row
DWORD imgsize; // The number of bytes occupied by the actual image data
DWORD numcolors; // The number of colors actually used, that is, the number of colors in the palette Array
Dword I;
If (HF = _ lopen (BMP filename, of_read) = hfile_error ){
MessageBox (hwnd, "filec: // test.bmp notfound! "," Errormessage ",
Mb_ OK | mb_iconexclamation );
Return false; // An error occurred while opening the file.
}
// Read the bitmapfileheader structure from the file and enter it in BF.
_ Lread (HF, (lpstr) & BF, sizeof (bitmapfileheader ));
// Read the bitmapinfoheader structure from the file and enter it in Bi.
_ Lread (HF, (lpstr) & BI, sizeof (bitmapinfoheader ));
/* We define a macro # define widthbytes (I) (I + 31)/32*4). As mentioned above, each row
The number of bytes must be an integer multiple of 4. You only need to call widthbytes (Bi. biwidth * bi. bibitcount ).
For example, for a 2-color image, if the image width is 31, each row needs to be stored with 31 characters.
The number of bytes must be an integer multiple of 4, so it should be 4, and biwidth = 31, bibitcou
Nt = 1, widthbytes (31*1) = 4, as we imagined. For example, if the image width is
31, each row requires 31 bytes of storage, because the number of bytes must be an integer multiple of 4, so it should be 32.
Biwidth = 31, bibitcount = 8, widthbytes (31*8) = 32, as we imagine. A few more
Example to verify */
// Linebytes indicates the number of bytes in each row.
Linebytes = (DWORD) widthbytes (Bi. biwidth * bi. bibitcount );
// Imgsize indicates the number of bytes occupied by the actual image data.
Imgsize = (DWORD) linebytes * bi. biheight;
// Numcolors indicates the number of colors actually used, that is, the number of colors in the color palette array.
If (Bi. biclrused! = 0)
Numcolors = (DWORD) Bi. biclrused; // If bi. biclrused is not zero, it is the actual image
// Number of colors used
Else // otherwise, the number of colors used is the bibitcount power of 2.
Switch (Bi. bibitcount ){
Case1:
Numcolors = 2;
Break;
Case4:
Numcolors = 16;
Break;
Case8:
Numcolors = 256;
Break;
Case24:
Numcolors = 0; // the color palette is not used for a true color chart.
Break;
Default:
// If the number of other colors is not processed, an error is returned.
MessageBox (hwnd, "invalidcolornumbers! "," Errormessage ",
Mb_ OK | mb_iconexclamation );
_ Lclose (HF );
Return false; // close the file and return false
}
If (BF. bfoffbits! = (DWORD) (numcolors * sizeof (rgbquad) + sizeof (bitmapfileheader)
+ Sizeof (bitmapinfoheader )))
{
// The calculated offset is inconsistent with the actual offset, which must be an error in the number of colors
MessageBox (hwnd, "invalidcolornumbers! "," Errormessage ",
Mb_ OK | mb_iconexclamation );
_ Lclose (HF );
Return false; // close the file and return false
}
BF. bfsize = sizeof (bitmapfileheader) + sizeof (bitmapinfoheader) + numcolors
* Sizeof (rgbquad) + imgsize;
// Allocate memory. The size is the length of the bitmapinfoheader structure plus the color palette + the actual bitmap data.
If (himgdata = globalalloc (ghnd, (DWORD) (sizeof (bitmapinfoheader) +
Numcolors * sizeof (rgbquad) + imgsize) = NULL)
{
// Memory Allocation Error
MessageBox (hwnd, "errorallocmemory! "," Errormessage ",
Mb_ OK | mb_iconexclamation );
_ Lclose (HF );
Return false; // close the file and return false
}
// The pointer lpimgdata points to the memory Zone
Lpimgdata = (lpbitmapinfoheader) globallock (himgdata );
// Locate the file pointer at the beginning of bitmapinfoheader.
_ Llseek (HF, sizeof (bitmapfileheader), seek_set );
// Read the file content into lpimgdata
_ Hread (HF, (char *) lpimgdata, (long) sizeof (bitmapinfoheader)
+ (Long) numcolors * sizeof (rgbquad) + imgsize );
_ Lclose (HF); // close the file
If (numcolors! = 0) // numcolors is not zero. The color palette is used.
{
// Allocate local memory for the logical palette. The size is the length of the logical palette structure plus numcolors.
// Palettentry size
Hpal = localalloc (lhnd, sizeof (logpalette) + numcolors * sizeof (paletteentry ));
// Pointer ppal pointing to the memory area
Ppal = (logpalette *) locallock (hpal );
// Enter the header of the logical color palette Structure
Ppal-> palnumentries = numcolors;
Ppal-> palversion = 0x300;
// Lprgb points to the start position of the palette.
Lprgb = (lprgbquad) (lpstr) lpimgdata + (DWORD) sizeof (bitmapinfoheader ));
// Enter each item
For (I = 0; I {
Ppal-> palpalentry [I]. pered = lprgb-> rgbred;
Ppal-> palpalentry [I]. pegreen = lprgb-> rgbgreen;
Ppal-> palpalentry [I]. peblue = lprgb-> rgbblue;
Ppal-> palpalentry [I]. peflags = (byte) 0;
Lprgb ++; // move the pointer to the next item
}
// Generate the logical palette. hpalette is a global variable.
Hpalette = createpalette (ppal );
// Release local memory
Localunlock (hpal );
Localfree (hpal );
}
// Obtain the device context handle
HDC = getdc (hwnd );
If (hpalette) // If the logical palette is generated just now
{
// Select the new logical palette to DC and save the old logical palette handle to hprevpalette.
Hprevpalette = selectpalette (HDC, hpalette, false );
Realizepalette (HDC );
}
// Generate a bitmap handle
Hbitmap = createdibitmap (HDC, (lpbitmapinfoheader) lpimgdata, (long) cbm_init,
(Lpstr) lpimgdata + sizeof (bitmapinfoheader) + numcolors * sizeof (rgbquad ),
(Lpbitmapinfo) lpimgdata, dib_rgb_colors );
// Select the original palette (if any) into the device context handle.
If (hpalette & hprevpalette)
{
Selectpalette (HDC, hprevpalette, false );
Realizepalette (HDC );
}
Releasedc (hwnd, HDC); // release the device context
Globalunlock (himgdata); // unlock the memory Zone
Return true; // success
}
In the above program, there are two points to note:
First, for the color palette, You need to configure the display, and then upload the. BMP file to generate a logical color palette.
The method is as follows: 1. allocate memory to the logical palette pointer. The size is the logical palette structure (logpalette)
Length plus numcolors palettentry size. (Each item in the palette is a paletteentry structure)
, 2. Fill in the header ppal of the logical color palette structure> palnumentries = numcolors; ppal-> palversion = 0x3
00; 3. Read the RGB values of the color palette from the file and enter them in each item. 4. Generate the logical palette: hpalette =
Createpalette (ppal)
Second, generate a bitmap handle, which is completed by the createdibitmap function. Hbitmap = Cr
Eatedibitmap (HDC, lpbitmapinfoheader) lpimgdata, (long) cbm_init, (lpstr) lpimgda
Ta + sizeof (bitmapinfoheader) + numcolors * sizeof (rgbquad), (lpbitmapinfo) lpimgda
Ta, dib_rgb_colors); createdibitmap is used to generate a bitmap irrelevant to the Windows Device. The
The first parameter of the function is the device context handle. If the bitmap uses the color palette, you must call createdibitm.
The AP selects the logical color palette to the device context, generates hbitmap, and then selects the original color palette to the device.
Next, and release the context. The second is the pointer to bitmapinfoheader. The third is the constant CB.
M_ini, no need to consider; item 4 is the pointer to the color palette; item 5 is the pointer to bitmapinfo (including bitma
Pinfoheader, color palette, and actual image data) pointer; the sixth item is the constant dib_rgb_colors, not
Usage considerations.
The device context is mentioned above. I believe that readers who have compiled Windows programs are no stranger to it. Here is a brief introduction.
. In Windows, operations such as display and printing are managed in a unified manner.
Each device has a complex data structure for maintenance. The device context refers to the data structure.
However, we cannot directly deal with the context of these devices. We can only reference the handle that identifies them (actually
An integer. Generated logical palette handle hpalette and bitmap handle H
Bitmap must be used to process the wm_paint message so that it can be displayed on the screen. The processing process is as follows:
Program.
Statichdc HDC, hmemdc;
Paintstruct pS;
Case wm_paint:
{
HDC = beginpaint (hwnd, & PS); // obtain the context of the screen device
If (hbitmap) // hbitmap is null at the beginning. If it is not null, the graph is displayed.
{
Hmemdc = createcompatibledc (HDC); // create a memory device context
If (hpalette) // has a color palette
{
// Select the color palette to the context of the screen device.
Selectpalette (HDC, hpalette, false );
// Select the color palette into the memory device context
Selectpalette (hmemdc, hpalette, false );
Realizepalette (HDC );
}
// Select the bitmap into the memory device context
SelectObject (hmemdc, hbitmap );
// Display bitmap
Bitblt (HDC, 0, 0, Bi. biwidth, Bi. biheight, hmemdc, 0, srccopy );
// Release the memory device context
Deletedc (hmemdc );
}
// Release the context of the screen device
Endpaint (hwnd, & PS );
Break;
}
In the above program, we call createcompatibledc to create a memory device context. Selectobje
The CT function selects the memory device context from the device-independent bitmap. Then we call the bitblt function to set
The backup context and the context of the screen device. Because all operations are performed in the memory
Fast.
The parameters of the bitblt function are as follows: 1. The context of the target device. In the preceding procedure,
If it is changed to print the device context, it is not to display the bitmap, but to print; 2. Point X coordinate in the upper left corner of the target rectangle; 3
. Y coordinate in the upper left corner of the target rectangle. In the above program, 2 and 3 are (0, 0), indicating to display them in the upper left corner of the window.
Angle; 4. The width of the target rectangle; 5. The height of the target rectangle; 6. Source device context. In the above program
Device context; 7. x coordinate in the upper left corner of the source rectangle; 8. Y coordinate in the upper left corner of the source rectangle; 9. operation method
Srccopy, which directly copies the source rectangle to the target rectangle. It can also be reversed, erased, and "and" operations.
For details, see VC ++ help. You can try to modify the, and 9 parameters.
To their meanings.
The lecture is finished. Is it boring? This is a bit boring, especially when you program windows
This is especially true when it is not clear. However, when a beautiful BMP image is displayed on the screen, you will still enjoy
Fen shouted "Yeah", at least I did that.
At last, we will introduce the command line compilation tips. Why do we need to compile with the command line? There are two main advantages:
First, you do not need to enter the IDE (integrated development environment), saving time and compiling speed.
Second, for a simple program, the. exe file can be directly generated by generating the project file .mdpor .mak.
Point, as shown in the following example.
After visual c ++ is installed, a vcvars32.bat file is generated in the bin directory.
Set correct environment variables during line compilation, such as the include directory for storing header files and the lib directory for storing library files
If you do not find the batch processing file, you can refer to the example below to do a batch processing by yourself.
@ Echo off
Set msdevdir = D:/msdev
Set vcosdir = Win95
Set Path = "% msdevdir %/bin"; "% msdevdir %/bin/% vcosdir %"; "% PATH %"
Set include = % msdevdir %/include; % msdevdir %/mfc/include; % include %
Set Lib = % msdevdir %/LIB; % msdevdir %/mfc/LIB; % lib %
Set vcosdir =
You just need to change the above "D:/msdev" to your own VC directory. Execute the batch in dosprompt
Run the SET command to view the newly set environment variables. As follows:
Path = D:/msdev/bin; D:/msdev/bin/Win95; C:/Win95; C:/Win95/command; C:/Win95/syst
Em;
Include = D:/msdev/include; D:/msdev/mfc/include;
Lib = D:/msdev/LIB; D:/msdev/mfc/LIB;
Now we can compile the command line. (You can also use ide to create a new project first.
Insert the. C and. RC files to the project and compile and run the program .)
First, compile the resource file, enter rc bmp. RC, generate the BMP. Res file, and then enter Cl BMP. c BMP. Res.
User32.lib gdi32.lib. then, BMP is generated. We can see that the project file is not used
For such a simple program, it is very convenient to compile using the command line. Good, run BMP. EXE,
Appreciate the fruits of your work today.
Note:
The command line compilation process is as follows:
Vcvars32
Rc bmp. RC
Cl bmp. c BMP. Res user32.lib gdi32.lib
Posted on: 2006-10-19, modified on: 2006-10-19, which has been browsed for 305 times and has commented on 0 recommendation complaints.

This article is transferred from
Http://blog.chinaunix.net/u/19671/showart_187280.html

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.