Creating Bitmaps

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 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 CE–based applications.

    To create a device-independent bitmap

  1. Call the CreateDIBSection function.

    CreateDIBSection creates a DIBSection, which contains all the information necessary for displaying the DIB.

  2. Call the SelectObject function to select the DIBSection into the device context.
  3. 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 RGBQUAD structures. 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 palettized with formats of 1, 2, 4, or 8 bits per pixel (bpp). For a 16 bpp or 32 bpp non-palettized 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.

    To create a device-dependent bitmap

  1. 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.

  2. 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.
  3. Call SelectObject to select the bitmap into the device context.

    Windows 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.

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);
  DeleteDC (hDC);

  return;  
}

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.

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 CE supports arbitrary bit pixel formats, which enable you to use blit functions among bitmaps with different pixel depths.