Creating a Bitmap with Hard-Coded Bits

You can create a bitmap and set its initial image to an array of bitmap bits by using the CreateDIBitmap function. This function creates a memory bitmap of a given size with a device-dependent color format; it initializes the bitmap image by translating a device-independent bitmap definition into the device-dependent format required by the display device and copying this device-dependent information to the memory bitmap. Typically, this method is used to create small bitmaps for use with pattern brushes, but it can also be used to create larger bitmaps.

NOTE:

Unless the bitmap is monochrome (that is, a bitmap having a single color plane and one bit per pixel), the memory bitmap created by CreateBitmap is device-specific, and therefore might not be suitable for display on some devices.

The following example creates a 64-by-32-pixel, monochrome bitmap; the
example initializes the bitmap by using the bits in the array Square.

HBITMAP hBitmap;

HDC hDC;

BYTE Square[] = {

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

.

.

.

HANDLE hDibInfo;

PBITMAPINFO pDibInfo;

if(pDibInfo = (PBITMAPINFO)LocalAlloc(LMEM_FIXED,

sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD)))

{

HBRUSH hOldBrush,hBrush;

pDibInfo->bmiHeader.biSize =

(long)sizeof(BITMAPINFOHEADER);

pDibInfo->bmiHeader.biWidth = 64L;

pDibInfo->bmiHeader.biHeight = 32;

pDibInfo->bmiHeader.biPlanes = 1;

pDibInfo->bmiHeader.biBitCount = 1;

pDibInfo->bmiHeader.biCompression=0L;

pDibInfo->bmiHeader.biSizeImage=0L;

pDibInfo->bmiHeader.biXPelsPerMeter=0L;

pDibInfo->bmiHeader.biYPelsPerMeter=0L;

pDibInfo->bmiHeader.biClrUsed=0L;

pDibInfo->bmiHeader.biClrImportant=0L;

pDibInfo->bmiColors[0].rgbRed = 0;

pDibInfo->bmiColors[0].rgbGreen = 0;

pDibInfo->bmiColors[0].rgbBlue = 0;

pDibInfo->bmiColors[1].rgbRed = 0xff;

pDibInfo->bmiColors[1].rgbGreen = 0xff;

pDibInfo->bmiColors[1].rgbBlue = 0xff;

hDC = GetDC(hWnd);

hBitmap = CreateDIBitmap (hDC,

(LPBITMAPINFOHEADER)&(pDibInfo->bmiHeader),

CBM_INIT,

(LPSTR) Square,

(LPBITMAPINFO)pDibInfo, DIB_RGB_COLORS);

ReleaseDC (hWnd, hDC);

DeleteObject(hBitmap);

LocalFree((HANDLE)pDibInfo);

}

The CreateDIBitmap function creates and initializes the bitmap before returning the bitmap handle. The width and height of the bitmap are 64 and 32 pixels, respectively. The bitmap has one bit for each pixel, making it a monochrome bitmap.

The Square array contains the bits used to initialize the bitmap. The BITMAPINFO data structure determines how the bits in the array are interpreted. It defines the width and height of the bitmap, how many bits (1, 4, 8 or 24) are used in the array to represent each pixel, and a table of colors for the pixels. Since the Square array defines a monochrome bitmap, the bit count per pixel is one and the color table contains only two entries, one for black and one for white. If a given bit in the array is zero, then GDI draws a black pixel for that bit; if it is one, then GDI draws a white pixel.

Since the Square array defines a monochrome bitmap, you could also call CreateBitmap to create the bitmap:

hBitmap = CreateBitmap (64, 32, 1, 1, (LPSTR) Square);

This is possible because all monochrome memory bitmaps are device independent. For color bitmaps, however, CreateBitmap cannot use the same bitmap-bit specification as can CreateDIBitmap.

Once you have created and initialized the bitmap, you can use its handle in subsequent GDI functions. If you want to change the bitmap, you can draw in it by selecting it into a memory device context. For more information, see “Creating and Filling a Blank Bitmap”. If you want to replace the bitmap image with another or change a portion of it, you can use the SetDIBits function to copy another array of bits into the bitmap. For example, the following function call replaces the current bitmap image with the bits in the array Circle:

BYTE Circle[] = {

.

.

.

};

SetDIBits(hDC, hBitmap, 0, 32, (LPSTR) Circle,

(LPBITMAPINFO)&myDIBInfo, DIB_RGB_COLORS);

The SetDIBits function copies the bits in the Circle array into the bitmap specified by the hBitmap variable. The array contains 32 scan lines, representing the image of a 64-by-32-pixel monochrome bitmap. If you want to retrieve the current bits in a bitmap before replacing them, you can use the GetDIBits function. It copies a specified number of scan lines from the bitmap into a device-independent bitmap specification. You can also use GetBitmapBits to retrieve bits from a monochrome bitmap.

Again, since the Circle array defines a monochrome bitmap, you could call SetBitmapBits instead to change the bitmap:

SetBitmapBits (hBitmap, 256, (LPSTR) Circle);

The preceding examples show how to create and modify a small bitmap. Typically you will not want to hard-code larger bitmaps in your application source code. Instead, you can store a larger bitmap in a device-independent bitmap file created by the Image Editor or other tools. A device-independent bitmap file consists of a BITMAPFILEHEADER data structure followed by a BITMAPINFO structure and an array of bytes that together define the bitmap.