Creating Bitmaps
A version of this page is also available for
4/8/2010
A bitmap is an array of bits that, when mapped to a rectangular pixel array on an output device, creates an image. Use bitmaps to create, modify, and store images.
Windows Embedded CE supports two types of bitmaps, device-dependent bitmaps (DDBs) and device-independent bitmaps (DIBs). A device-dependent bitmap does not have its own color table and therefore can be properly displayed only by a device with the same display memory organization as the one on which it was created. A device-independent bitmap, on the other hand, generally has its own color table and therefore can be displayed on multiple devices. It is recommended that you use DIBs in Windows Embedded CE–based applications.
To create a device-independent bitmap
Call the CreateDIBSection function.
CreateDIBSection creates a DIBSection, which contains all the information necessary for displaying the DIB.
Call the SelectObject function to select the DIBSection into the device context.
Select the DIBSection again and call DeleteObject to delete the DIBSection when finished.
The BITMAPINFO structure defines the dimensions and color information for a DIB. This structure consists of a BITMAPINFOHEADER structure and an array of two or more RGBQUADstructures. The BITMAPINFOHEADER structure contains information about the dimensions and color format of a DIB. Each RGBQUAD structure defines one bitmap color. The BITMAPINFO structure must include a color table if the images are palletized with formats of 1, 2, 4, or 8 bits per pixel (bpp). For a 16 bpp or 32 bpp non-palletized image, the color table must be three entries long; the entries must specify the value of the red, green, and blue (RGB) bitmasks. Because GDI ignores the color table for 24-bpp bitmaps, you should store the image pixels in RGB format.
Note
Windows Embedded CE does not support 322 bitfields devices.
To create a device-dependent bitmap
Call CreateCompatibleDC to create a memory device context.
This function creates a device context compatible with the specified device. The device context contains a single-bit array that serves as a placeholder for a bitmap.
Call CreateBitmap or CreateCompatibleBitmap to create the bitmap. If calling CreateCompatibleBitmap, be sure that you specify a screen device context rather than a memory device context; otherwise, you will get a device context to a 1-bpp device.
Call SelectObject to select the bitmap into the device context.
Windows Embedded CE then replaces the single-bit array with an array large enough to store color data for the specified rectangle of pixels.
When you draw using the handle returned by CreateCompatibleDC, the output does not appear on a device's drawing surface; rather, it is stored in memory. To copy the image stored in memory to a display device, call the BitBlt function. BitBlt copies the bitmap data from the bitmap in the source device context into the bitmap in the target device context. In this case, the source device context is the memory device context, and the target device context is the display device context. Thus, when BitBlt completes the transfer, the image appears on the screen. By reversing the source and target device contexts, you can call BitBlt to transfer images from the screen into memory.
The following code example shows how to create a memory device context, how to use a CreateCompatibleBitmap to create a bitmap, and how to use BitBlt to copy bitmap data from the source device context to the target device context.
Note
To make the following code example easier to read, error checking is not included. This code example should not be used in a release configuration unless it has been modified to include secure error handling.
VOID BitmapDemo (HWND hwnd)
{
HDC hDC, // Handle to the display device context
hDCMem; // Handle to the memory device context
HBITMAP hBitmap, // Handle to the new bitmap
hOldBitmap; // Handle to the old bitmap
static int iCoordinate[200][4];
int i, j,
iXSrc, iYSrc, // x and y coordinates of the source
// Rectangle's upper-left corner
iXDest, iYDest, // x and y coordinates of the destination
// Rectangle's upper-left corner
iWidth, iHeight; // Width and height of the bitmap
// Retrieve the handle to a display device context for the client
// area of the window (hwnd).
if (!(hDC = GetDC (hwnd)))
return;
// Create a memory device context compatible with the device.
hDCMem = CreateCompatibleDC (hDC);
// Retrieve the width and height of windows display elements.
iWidth = GetSystemMetrics (SM_CXSCREEN) / 10;
iHeight = GetSystemMetrics (SM_CYSCREEN) / 10;
// Create a bitmap compatible with the device associated with the
// device context.
hBitmap = CreateCompatibleBitmap (hDC, iWidth, iHeight);
// Select the new bitmap object into the memory device context.
hOldBitmap = SelectObject (hDCMem, hBitmap);
for (i = 0; i < 2; i++)
{
for (j = 0; j < 200; j++)
{
if (i == 0)
{
iCoordinate[j][0] = iXDest = iWidth * (rand () % 10);
iCoordinate[j][1] = iYDest = iHeight * (rand () % 10);
iCoordinate[j][2] = iXSrc = iWidth * (rand () % 10);
iCoordinate[j][3] = iYSrc = iHeight * (rand () % 10);
}
else
{
iXDest = iCoordinate[200 - 1 - j][0];
iYDest = iCoordinate[200 - 1 - j][1];
iXSrc = iCoordinate[200 - 1 - j][2];
iYSrc = iCoordinate[200 - 1 - j][3];
}
// Transfer pixels from the source rectangle to the destination
// rectangle.
BitBlt (hDCMem, 0, 0, iWidth, iHeight, hDC, iXDest, iYDest,
SRCCOPY);
BitBlt (hDC, iXDest, iYDest, iWidth, iHeight, hDC, iXSrc, iYSrc,
SRCCOPY);
}
}
// Select the old bitmap back into the device context.
SelectObject (hDC, hOldBitmap);
// Delete the bitmap object and free all resources associated with it.
DeleteObject (hBitmap);
// Delete the memory device context and the display device context.
DeleteDC (hDCMem);
ReleaseDC (hDC);
return;
}
Blitting
Bit block transfer (blit) functions, such as BitBlt, can be used to modify as well as transfer bitmaps. These functions modify a destination bitmap by combining it with a pen, a brush, and, in some cases, a source bitmap, in a format specified by a raster operation (ROP) code. Each ROP code specifies a unique logical pattern for combining graphics objects. For example, the SRCCOPY ROP simply copies a source bitmap to a destination bitmap, while the MERGECOPY ROP merges the colors of a source rectangle with a specified pattern. For more information, see Raster Operation Codes.
The following table shows the ROP code types.
ROP type | Description |
---|---|
ROP2 |
Combines a pen or brush with a destination bitmap in one of 16 possible combinations. |
ROP3 |
Combines a brush, a source bitmap, and a destination bitmap in one of 256 possible combinations. |
ROP4 |
Uses a monochrome mask bitmap to combine a foreground ROP3 and a background ROP3. The mask uses zeros and ones to indicate the areas where each ROP3 will be used. |
When the source and destination bitmaps are different sizes, you can call the StretchBlt function to perform a blit between the two bitmaps. StrechBlt copies a bitmap from a source rectangle into a destination rectangle, stretching or compressing the bitmap to fit the destination rectangle.
Additionally, you can call the PatBlt function to paint a selected rectangle using a selected brush and an ROP3 code. You can also call the TransparentImage to transfer all portions of a bitmap except for those drawn in a specified transparent color. This function is especially useful for transferring non-rectangular images such as icons.
Note
Windows Embedded CE supports arbitrary bit pixel formats, which enable you to use blit functions among bitmaps with different pixel depths.
Blit operations are always performed as if they were on left-to-right- (LTR) oriented displays. The coordinate system of a right-to-left- (RTL) oriented display is flipped and has its origin in the upper right corner of the display rather than the upper left corner. A blit on an RTL-oriented display will appear in the same physical location as it would if the coordinate system were in LTR mode. As a result, pixel addressing algorithms for displays in RTL mode are different than those in LTR mode. The following equations describe the two addressing methods.
- Left-to-Right
pBitmapPixel(x,y) = pStartPixel + x * rowlength + y * pixelsize
- Right-to-Left
pBitmapPixel(x,y) = pStartPixel + (x + 1) * rowlength - pixelsize - y * pixelsize
The ROP code NOMIRRORBITMAP is not valid. The ROP code 0x80000000 is ignored.