The above section Code It is designed to call bitmap from a resource, but you can easily modify it to call bitmap from an external file, then try to call bitmap from an external file. For external calls, remember to add the lr_loadfromfile flag when calling the LoadImage () function. The most amazing thing is that the bitblt () function automatically converts the pixel format. For example, when we put a 24-Bit Bitmap into the memory device context, we transmit (copy) it to the surface of a 16-bit color depth, all colors will be correctly displayed, so you don't have to worry about whether the pixel format is 555 or 565. It's very convenient, right?
If you want to control the actual process of Bitmap transfer, rather than using simple functions such as bitblt (), you have two options. First, you can modify this function. You need to use the bmbits Member of the bitmap structure. It is an lpvoid pointer variable that makes up the bit of the image. Second, if you really want to control the call process of an image, you can write a function by yourself. The idea is to use a standard I/O function to open an image file and then read it. To do this, you need to understand the structure of the bitmap file. We will not involve writing such functions, because it is enough for us, but I still want to pave the way for the future.
Bitmap format
Fortunately, you have to write a bitmap function by yourself. A Win32 structure Bitmap header file can be used. Read the information of this header file and use a simple function like fread. All bitmap files have such a header file that contains all information about the bitmap. Bitmapfileheader is the name of the header file structure. The following figure shows its prototype:
typedef struct tagbitmapfileheader {// bmfh
word bftype; // file type-must be "BM" for bitmap
DWORD bfsize; // size in bytes of the bitmap file
word bfreserved1; // must be zero
word bfreserved2; // must be zero
DWORD bfoffbits; // offset in bytes from the bitmapfileheader
// structure to the bitmap bits
} bitmapfileheader;
I will not describe these members in detail, because the comments have already been quite clear. You only need to use fread () to read them. Check whether the bftype member is equal to the character "BM". If yes, you are processing a valid bitmap. After that, another header file needs to be read, which contains the size, compression type, and other image information of the bitmap. The following is its structure:
typedef struct tagbitmapinfoheader {// bmih
DWORD bisize; // number of bytes required by the structure
long biwidth; // width of the image in pixels
long biheight; // height of the image in pixels
word biplanes; // number of planes for target device-must be 1
word bibitcount; // bits per pixel-1, 4, 8, 16, 24, or 32
DWORD bicompression; // type Of compression-bi_rgb for uncompressed
DWORD bisizeimage; // size in bytes of the image
long bixpelspermeter; // horizontal resolution in Els pixper meter
long biypelspermeter; // vertical resolution in pixels per meter
DWORD biclrused; // number of colors used
DWORD biclrimportant; // number of colors that are important
} bitmapinfoheader;
only a few Members need to explain.. First, pay attention to the compression format. Most bitmaps require decompression. The most common bitmap compression format is run-length encoding (RLE), but it can only be applied to 4-bit or 8-bit images. In this case, the member bicompression will be bi_rle4 and bi_rle8, respectively, we will not discuss this compression format, but it is really simple and easy to understand. If you want to know it, there will be no trouble.
Second, for high-color bitmaps, biclrused and biclrimportant are usually set to 0, so you don't need to care too much about them. For uncompressed bitmaps such as bi_rgb, the member bisizeimage will also be set to 0. Finally, for our purpose, other structural members are not very important. We only need to pay attention to the length, width, and color depth of the bitmap (biwidth, biheight, and bibitcount ).
After reading the information of these header files, if the bitmap is 8-bit or the following color depth (that is, the color palette mode), the information of the color palette follows the information. Perhaps unexpectedly, the palette information is not stored in the paletteentry structure, but in the rgbquad structure. The rgbquad structure is as follows:
Typedef struct tagrgbquad {// rgbq
Byte rgbblue;
Byte rgbgreen;
Byte rgbred;
Byte rgbreserved;
} Rgbquad;
Don't ask me why Red, green, and blue are arranged in reverse order. This is the case! Read the data in rgbquad and pass the data to the array of the DirectDraw palette. Remember to set the peflag of each paletteentry to pc_nocollapse.
Then (the color palette information does not exist because it does not exist in the high-color mode). You will find the image bits, and you may think of creating a pointer, allocate enough space in the memory to control the image bit data and then read them. That's right. I'm about to do this. Assume that the information header file stored in the bitmapinfoheader structure is called info, and your image bit pointer is called fptr. The implementation code is as follows:
Uchar * buffer = (uchar *) malloc (info. bisizeimage );
Fread (buffer, sizeof (uchar), info. bisizeimage, fptr );
Remember, in some cases, the bisizeimage value may be 0, so it is necessary to check it before running the above Code. If it is set to 0, you will have to calculate how many pixels the image consists of and how many bytes each pixel requires.
Writing your own bitmap to call a function is not difficult. But if you don't think it is necessary, use the method we will introduce. This topic has come to an end. Let's take a look at the essence of DirectDraw: bit block transmission.