MFC technology accumulation-based on the MFC dialog box Class 3.
3.3.2Create Image painter to load bitmap
1. First, import a bitmap in the Resource View. The bitmap size is 96 × 96 pixels;
2. In the main dialog box, add a static text resource with the IDC_BITMAPAREA ID and a button resource with the IDB_LOADBITMAP ID;
3. Edit the message Association function of the button (IDB_LOADBITMAP), 3.6:
Note that the default bitmap size of 3.5 is 96*96 pixels. When editing the bitmap display area, that is, the static text area marked in Figure 3.5. The attribute size is 64 × 64. Here, the unit is regarded as the logical unit and the dimension is 1. In the debug mode shown in Figure 3.6, it is confirmed that the display area drawn under the logical coordinate has a proportional relationship with the actual size (I tested a 2/3 relationship ), that is, in the sample code, the size of the region obtained by mywnd-> GetClientRect (& rc) is the pixel coordinate.
The reason for this attention is that this section uses the creation of image pasters to display bitmaps. If the display area is of any size, you will find that the display effect is shown in 3.7:
3.3.3CreateDIB (device-independent bitmap)Image painter
Use the CBrush: CreateDIBPatternBrush function to create a DIB image painting brush. First, the data structure of a typical DIB image consists of the following four parts:
1. BITMAPFILEHEADER:
Typedef struct tagBITMAPFILEHEADER {// Bmfh
WORD bfType; // file type, which must be "BM" (0x4D42)
DWORD bfSize; // the size of the bitmap file, in bytes.
WORD bfReserved1; // reserved, must be 0
WORD bfReserved2; // reserved, must be 0
DWORD bfOffBits; // The number of deviations between the actual image data and the start point of the file header
} BITMAPFILEHEADER;
2. BITMAPINFOHEADER:
Typedef struct tagBITMAPINFOHEADER {// Bmih
DWORD biSize; // The number of bytes occupied by the struct.
LONG biWidth; // The bitmap image width, in pixels.
LONG biHeight; // The height of the bitmap. Unit: pixels.
WORD biPlanes; // Number of color planes on the device, which must be 1
WORD biBitCount // stores the binary digits occupied by each pixel. Values: 1, 4, 8, 16, 24, and 32.
DWORD biCompression; // whether to compress and Store Image Data
DWORD biSizeImage; // specify the image size, in bytes
LONG biXPelsPerMeter; // horizontal resolution of the image, in pixels per meter
LONG biYPelsPerMeter; // vertical resolution of the image, in the unit of pixels per meter
DWORD biClrUsed; // The number of colors actually used in the color index table in the image
DWORD biClrImportant; // number of important colors in the image. If the value is 0, all colors are considered important.
} BITMAPINFOHEADER;
Explanation:BiSizeImage:BiSizeImage = biwidth' * biHeight * each pixel occupies the number of bytes. For bitmap data, the number of bytes in each row must be a multiple of 4, that is,"Biwidth' * bytes occupied by each pixel"Is a multiple of 4. Therefore, when the actual image data width biWidth is not a multiple of 4, bitmap data must be filled.
BiCompression:For the bottom-up bitmap (bitmap reading method is from bottom up) compression type (bitmap reading method from top down cannot be compressed ):
BI_RGB: no compression mode
BI_RLE8 and BI_RLE4: view the Bitmap Compression of MSDN.
BI_BITFIELDS: for 16 bits or 32bits bitmap, biCompression = BI_BITFIELDS. The color palette contains three DWORD color masks to specify the R, G, and B Components in the pixel color.
BiClrUsed:Specifies the number of colors actually used in the bitmap image. If the value is 0, the actual number of colors used in the image is the same as the maximum number of colors specified in the biBitCount member.If the bitmap isPacked bitmap(InBITMAPINFOThe data structure is followed by the bitmap data group, which is referenced by a pointer .)BiClrUsedRequired0Or the actual number of colors in the palette.
3. The structure of the color palette data is defined as follows:
Typedef struct tagRGBQUAD {// Rgbq
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved; // The value must be 0.
} RGBQUAD;
There is no color palette for a true color chart (24bits bitmap, that is, biBitCount = 24.
4. The fourth part is the actual bitmap data.
Next, we will explainCBrush: CreateDIBPatternBrush:
BOOL CreateDIBPatternBrush (const void *LpPackedDIB, UINTNUsage);
LpPackedDIB: Points toPacked DIB
NUsage: In the BITMAPINFO struct, the member bmiColors [] indicates the clear RGB value or the index value of the logical palette. If nUsage =DIB_RGB_COLORSIndicates that the color table contains clear RGB values. If nUsage =DIB_PAL_COLORSThe color table is a 16-bit index array.
The sample code for implementation is as follows:
Void CFDlg: OnLoadbitmap () {// TODO: Add your control notification handler code here unsigned char * ImageBuffer = new unsigned char [sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 256]; unsigned char * ImageInfo = NULL; BITMAPFILEHEADER m_bitmapfileheader; BITMAPINFOHEADER * infoheader; RGBQUAD * palette; BITMAPINFO * bmi; FILE * ImageFile; unsigned int BytesSize = 0; if (NULL = (ImageFile = fopen ("D: \ 10.bmp "," Rb ") // read a bitmap from disk D {printf (" can not open the image file! "); Return;} else {fread (& m_bitmapfileheader, sizeof (BITMAPFILEHEADER), 1, ImageFile); // read the file header // read the information header and the color palette data block fread (ImageBuffer, m_bitmapfileheader.bfOffBits-sizeof (BITMAPFILEHEADER), 1, ImageFile); bmi = (BITMAPINFO *) ImageBuffer; infoheader = & (bmi-> bmiHeader); palette = bmi-> bmiColors; // Bitmap header and total number of bytes of actual data BytesSize = m_bitmapfileheader.bfOffBits-sizeof (BITMAPFILEHEADER) + (infoheader-> biWidth * infoheader-> biHeight * (infoheader-> biBitCount/8 ));
ImageInfo = new unsigned char [BytesSize]; fseek (ImageFile, sizeof (BITMAPFILEHEADER), SEEK_SET); // skip the file header fread (ImageInfo, BytesSize, 1, ImageFile ); CWnd * mywnd = GetDlgItem (IDC_BITMAPAREA); CClientDC dc (mywnd); RECT rc; CBrush mybrush; CBrush * oldbrush; mywnd-> GetClientRect (& rc); mybrush. createDIBPatternBrush (ImageInfo, DIB_RGB_COLORS); oldbrush = dc. selectObject (& mybrush); dc. fillRect (& rc, & mybrush); dc. selectObject (oldbrush); mybrush. deleteObject ();} delete [] ImageBuffer; delete [] ImageInfo ;}