Addressing pixels in a monochrome DIB (329004)



The information in this article applies to:

  • Microsoft Platform Software Development Kit (SDK) 1.0

This article was previously published under Q329004

SUMMARY

When working with monochrome Device-Independent Bitmaps (DIBs), you may want to work directly with the surface bits of the image. By working directly with the surface bits, you can bypass the graphics device interface (GDI) and obtain better performance.

MORE INFORMATION

To get the offset of a pixel in the surface of a monochrome DIB or DIB section surface, you must perform several calculations:
  • Locate the scanline of the pixel in the surface bits by taking the Y coordinate of the pixel and multiplying it by the DWORD aligned scanline width.
  • Locate the byte that contains the pixel in the scanline by taking the X coordinate and dividing it by 8.
  • Locate the bit in the byte by taking the X coordinate and moding it by 8 and subtracting it from 7 (to account for the bit ordering).
The following code demonstrates this procedure:
/*******************************************************************\ 
*                                                                   *
* BOOL TogglePixel(HBITMAP hbm, int x, int y);                      *
*                                                                   *
* Toggles a pixel in a monochrome DIB section                       *
*                                                                   *
* Parameters:                                                       *
*   hbm - handle to a DIB section                                   *
*   x   - X coordinate of the pixel to toggle                       *
*   y   - Y coordinate of the pixel to toggle                       *
*                                                                   *
* Notes:                                                            *
*   This function only works with DIB sections because there is no  *    
*   way to get a pointer to the surface bits of a device dependent  *
*   bitmap.                                                         *
*                                                                   *
\*******************************************************************/ 
BOOL TogglePixel(HBITMAP hbm, int x, int y)
{
    BITMAP  bm;
    LPBYTE  pByte;
    int     iByte, iBit;

    // Retrieve the surface information.
    if (!GetObject(hbm, sizeof(bm), &bm))
        return FALSE;  // Bail, it's not a valid HBITMAP

    // Check the bit depth of the surface.
    if (bm.bmPlanes * bm.bmBitsPixel != 1)
        return FALSE;  // Bail, it's not monochrome 

    // Get a BYTE pointer to the surface bits.
    pByte = (LPBYTE)bm.bmBits;
    
    // Make sure you have a DIB section (per Q187539).
    if (!pByte)
        return FALSE;  // Bail, it's not a DIB section

    // Make sure the coordinates are valid.
    if ((x < 0) || (y < 0) || (x >= bm.bmWidth) || (y >= bm.bmHeight))
        return FALSE;  // Coordinate is not within the surface  
    
    // Get to the scanline you want.
    pByte += ALIGNULONG(bm.bmWidthBytes) * (bm.bmHeight - y - 1);

    // Find the Byte and Bit you need to set.
    iByte = x >> 3;       // Divide by 8 to locate the byte 
    iBit  = 7 - (x & 7);  // Mod by 8 to locate the bit within the byte

    // Adjust the bits pointer to point to the right byte.
    pByte += iByte;

    // Flip the bit.
    *pByte ^= (1 << iBit);

    return TRUE;
}
				

Modification Type:MinorLast Reviewed:5/10/2006
Keywords:kbDSWGDI2003Swept kbGDI kbinfo KB329004