KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q80080: HOWTO: Convert Between Device-Dependent Bitmaps and DIBs

Article: Q80080
Product(s): Microsoft Windows Software Development Kit
Version(s): 3.0,3.1
Operating System(s): 
Keyword(s): kbOSWin310 kbDSupport kbOSWin300 kbSDKWin16 kb16bitonly
Last Modified: 23-JUL-2001

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Windows Software Development Kit (SDK) for Windows versions 3.0, 3.1 
-------------------------------------------------------------------------------

SUMMARY
=======

This article explains the basic steps involved in converting between device-
dependent bitmaps (DDBs) and Windows 3.0 style device-independent bitmaps
(DIBs). This article assumes some background knowledge of bitmaps, DIBs,
palettes, and memory allocation.

The SHOWDIB sample application provided in versions 3.0 and 3.1 of the Windows
SDK, the WINCAP sample application available in the Microsoft Download Center,
and the DIBVIEW sample application provided in version 3.1 of the Windows SDK
and in the Professional Edition of Visual C++ each demonstrate the steps
described in this article.

MORE INFORMATION
================

Use the following steps to convert a DDB to a DIB:

1. Initialize the BITMAPINFOHEADER data structure.
  a. Set biSize to sizeof(BITMAPINFOHEADER).

  b. Set biWidth to the width of the bitmap.

  c. Set biHeight to the height of the bitmap.

  d. Set biPlanes to 1.

  e. Set biBitCount to the bitmap bmPlanes multiplied by bmBitsPixel. This
     value can contain only the values 1, 4, 8, or 24.

  f. Set biCompression to the desired format (usually BI_RGB).

  g. All other fields can be set to zero.

  Code to initialize the BITMAPINFOHEADER data structure might look like the
  following:

     BITMAPINFOHEADER bmi;
     BITMAP           bm;
     .
     .
     .
     bmi.biSize          = sizeof(BITMAPINFOHEADER);
     bmi.biWidth         = bm.bmWidth;
     bmi.biHeight        = bm.bmHeight;
     bmi.biPlanes        = 1;
     bmi.biBitCount      = bm.bmPlanes * bm.bmBitsPixel;

     if (bmi.biBitCount <= 1)
       bmi.biBitCount = 1;
     else if (bmi.biBitCount <= 4)
       bmi.biBitCount = 4;
     else if (bmi.biBitCount <= 8)
       bmi.biBitCount = 8;
     else
       bmi.biBitCount = 24;

     bmi.biCompression   = BI_RGB;
     bmi.biSizeImage     = 0;
     bmi.biXPelsPerMeter = 0;
     bmi.biYPelsPerMeter = 0;
     bmi.biClrUsed       = 0;
     bmi.biClrImportant  = 0;

2. If there is a logical palette associated with the bitmap, select the palette
  into the desired device context using SelectObject(), then realize the
  palette with RealizePalette().

3. Allocate a block of memory large enough to store the BITMAPINFOHEADER
  structure and the color table for the DIB. The color table is an array of
  RGBQUAD structures that contain the colors used by the image. The size of the
  color table is the number of colors multiplied by sizeof(RGBQUAD). The number
  of colors is found using the biBitCount field in BITMAPINFOHEADER, which
  specifies the color resolution (bits per pixel). For example, 1 bit-per-pixel
  means monochrome (2 colors), 4 bits-per-pixel means 16 colors, and 8
  bits-per-pixel means 256 colors. For a 24-bit color image, however, there is
  no color table.

4. Call the GetDIBits() function with the desired device context (DC), a pointer
  to the memory block as lpBitsInfo, and NULL as the lpBits parameter. Doing so
  instructs the device driver to fill in the biSizeImage field of the
  BITMAPINFOHEADER structure (this field should have been initialized to 0 in
  step 1). The biSizeImage field specifies the amount of memory required (in
  bytes) to store the bits that make up the image of the DIB. If this field
  remains 0 after calling GetDIBits(), the application must calculate
  biSizeImage using the following formula:

  ((((biWidth * biBitCount) + 31) & ~31) >> 3) * biHeight

  This formula is required because each scan line of the image is aligned on a
  DWORD boundary.

5. Reallocate the memory block containing the BITMAPINFOHEADER and color table
  to provide additional memory to store the bits of the DIB.

6. Call GetDIBits() with the desired DC, a pointer to the memory block as
  lpBitsInfo, a pointer to the buffer for the bitmap bits as lpBits, and wUsage
  as DIB_RGB_COLORS. This stores the bits of the DIB with the BITMAPINFOHEADER
  structure and completes the color table.

In the sample applications listed above, the DibFromBitmap() function in the
DIB.C file of SHOWDIB, the BitmapToDIB() function in the DIBUTIL.C file of
WINCAP, and the BitmapToDIB() function in the DIB.C file of DIBVIEW demonstrate
the process above.

NOTE: The first two samples convert bitmaps into Windows 3.0 style DIBs and do
not support OS/2-style DIBs. DIBVIEW does support OS/2-style DIBs.

For more information on the Windows 3.0-style DIB format, see the documentation
for the BITMAPINFO, BITMAPINFOHEADER, and RGBQUAD structures in the "Microsoft
Windows Software Development Kit Reference Volume 2" version 3.0 manual and in
the Windows 3.1 SDK "Programmer's Reference, Volume 3: Messages, Structures, and
Macro's" manual.

To convert a DIB to a DDB, do the following:

1. Create a logical palette from the information in the DIB color table.
  Complete a LOGPALETTE data structure using the color values found in the
  color table, then call CreatePalette().

2. Select the logical palette into the desired device context using
  SelectObject(), then realize the palette using RealizePalette().

3. Call CreateDIBitmap() using the desired DC and the pointer to the DIB as the
  lpInfoHeader parameter. This function returns a handle to a DDB.

In the sample applications listed above, the BitmapFromDib() function in the
DIB.C file of SHOWDIB, the DIBToBitmap() function in the DIBUTIL.C file of
WINCAP, and the DIBToBitmap() function in the DIB.C file of DIBVIEW demonstrate
the process above.

Additional query words:

======================================================================
Keywords          : kbOSWin310 kbDSupport kbOSWin300 kbSDKWin16 kb16bitonly 
Technology        : kbAudDeveloper kbWin3xSearch kbSDKSearch kbWinSDKSearch kbWinSDK300 kbWinSDK310
Version           : :3.0,3.1
Issue type        : kbhowto

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.