Thread: Transparent bitmaps

  1. #1

    Transparent bitmaps

    I'm loading bitmaps using the LoadImage function and having it make the Gray(192,192,192) pixels COLOR_3DFACE but is there a way for me to change this at a stage?

    If my control has a certain state ( selected ) I want the corresponding bitmap to have a different background color and border. But the COLOR_3DFACE part of the bitmap remains the same when I draw the background under it ... so I need to be able to change the background (COLOR_3DFACE) of the bmp to another color, the color that I am painting, so that it will appear transparent. And then I need to be able to reset it after I'm finished drawing for that state.

    [edit:] Or, I could just use an icon right? They have a transparent area?? If so, anyone know of a free tool to convert bmp to ico?

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    If you're nor using/targetting win9x then you could use TransparentBlt (leaks resources under win9x).

    If that's no good, then read this article which, although old, is a good source of information on different techniques for creating and manipulating transparent bitmaps.

    >>Or, I could just use an icon right? They have a transparent area?? If so, anyone know of a free tool to convert bmp to ico?<<

    Icons contain a 'normal' bitmap and a monochrome mask image - read the above mentioned article for an explanation of how mask and image are combined to create transparency. If you want a bitmap to icon converter i'm sure a web-search will turn up heaps or you could always get the ico file format from wotsit and write your own.

    Actually, there's a much better source of information on icons (if you're interested) here.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    What about TransparentImage()?? Does it suffer from leaks on 9x?

    [edit:] Well it looks like I can't even use TransparentImage or AlphaBlend because my libraries are out of date!

    I'll have to settle for TransparentBlt I guess or maybe I'll find something in those links.

    Thanks.
    Last edited by Mithoric; 03-11-2004 at 08:06 AM.

  4. #4
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    I grabbed the following TransparentBlt replacement from a Windows Development Network article. The author claims that it fixes the bug for Win9x machines.

    Code:
    bool TransparentBltU(
         HDC dcDest,         // handle to Dest DC
         int nXOriginDest,   // x-coord of destination upper-left corner
         int nYOriginDest,   // y-coord of destination upper-left corner
         int nWidthDest,     // width of destination rectangle
         int nHeightDest,    // height of destination rectangle
         HDC dcSrc,          // handle to source DC
         int nXOriginSrc,    // x-coord of source upper-left corner
         int nYOriginSrc,    // y-coord of source upper-left corner
         int nWidthSrc,      // width of source rectangle
         int nHeightSrc,     // height of source rectangle
         UINT crTransparent  // color to make transparent
      )
    {
         if (nWidthDest < 1) return false;
         if (nWidthSrc < 1) return false;
         if (nHeightDest < 1) return false;
         if (nHeightSrc < 1) return false;
    
         HDC dc         = CreateCompatibleDC(NULL);
         HBITMAP bitmap = CreateBitmap(nWidthSrc, nHeightSrc, 1,
                                        GetDeviceCaps(dc, BITSPIXEL), NULL);
    
         if (bitmap == NULL)
             return false;
    
         HBITMAP oldBitmap = (HBITMAP)SelectObject(dc, bitmap);
    
         if (!BitBlt(dc, 0, 0, nWidthSrc, nHeightSrc, dcSrc,
                         nXOriginSrc, nYOriginSrc, SRCCOPY))
             return false;
    
         HDC maskDC = CreateCompatibleDC(NULL);
         HBITMAP maskBitmap = CreateBitmap(nWidthSrc,
                nHeightSrc, 1, 1, NULL);
    
         if (maskBitmap == NULL)
             return false;
    
         HBITMAP oldMask =  (HBITMAP)SelectObject(maskDC,
                maskBitmap);
    
         SetBkColor(maskDC, RGB(0,0,0));
         SetTextColor(maskDC, RGB(255,255,255));
         if (!BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,NULL,
                         0,0,BLACKNESS))
             return false;
    
         SetBkColor(dc, crTransparent);
         BitBlt(maskDC, 0,0,nWidthSrc,nHeightSrc,dc,0,0,SRCINVERT);
    
         SetBkColor(dc, RGB(0,0,0));
         SetTextColor(dc, RGB(255,255,255));
         BitBlt(dc, 0,0,nWidthSrc,nHeightSrc,maskDC,0,0,SRCAND);
    
         HDC newMaskDC = CreateCompatibleDC(NULL);
         HBITMAP newMask;
         newMask = CreateBitmap(nWidthDest, nHeightDest, 1,
                    GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);
    
         if (newMask == NULL)
         {
             SelectObject(dc, oldBitmap);
             DeleteDC(dc);
             SelectObject(maskDC, oldMask);
             DeleteDC(maskDC);
              DeleteDC(newMaskDC);
             return false;
         }
    
         SetStretchBltMode(newMaskDC, COLORONCOLOR);
         HBITMAP oldNewMask = (HBITMAP) SelectObject(newMaskDC,
                newMask);
         StretchBlt(newMaskDC, 0, 0, nWidthDest, nHeightDest,
                maskDC, 0, 0, nWidthSrc, nHeightSrc, SRCCOPY);
    
         SelectObject(maskDC, oldMask);
         DeleteDC(maskDC);
    
         HDC newImageDC = CreateCompatibleDC(NULL);
         HBITMAP newImage = CreateBitmap(nWidthDest, nHeightDest,
                    1, GetDeviceCaps(newMaskDC, BITSPIXEL), NULL);
    
         if (newImage == NULL)
         {
             SelectObject(dc, oldBitmap);
             DeleteDC(dc);
             DeleteDC(newMaskDC);
             return false;
         }
    
         HBITMAP oldNewImage = (HBITMAP)SelectObject(newImageDC,
                    newImage);
         StretchBlt(newImageDC, 0, 0, nWidthDest, nHeightDest,
                    dc, 0, 0, nWidthSrc, nHeightSrc, SRCCOPY);
    
         SelectObject(dc, oldBitmap);
         DeleteDC(dc);
    
         BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest,
                    nHeightDest, newMaskDC, 0, 0, SRCAND);
    
         BitBlt( dcDest, nXOriginDest, nYOriginDest, nWidthDest,
                nHeightDest, newImageDC, 0, 0, SRCPAINT);
    
         newImage = (HBITMAP)SelectObject(newImageDC, oldNewImage);
         DeleteObject(newImage) ;
         DeleteDC(newImageDC);
         newMask  = (HBITMAP)SelectObject(newMaskDC, oldNewMask);
         DeleteObject(newMask) ;
         DeleteDC(newMaskDC);
         DeleteDC(dc) ;
         DeleteObject(bitmap) ;
    
         return true;
    }

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    That looks like an implementation of The Black Source Method in that old msdn article I gave a link to in a previous post in this thread.

    Still, it's always useful to have a concrete example.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    Nice, I'll have a go at putting that in..


    [edit:] Thanks people, I have it working fine!
    Last edited by Mithoric; 03-11-2004 at 03:36 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Transparent, Editbox, HOLLOW_BRUSH, Marking text?
    By Dampy in forum Windows Programming
    Replies: 6
    Last Post: 09-22-2008, 07:17 PM
  2. Transparent panels overlapped
    By AtomRiot in forum C# Programming
    Replies: 3
    Last Post: 04-21-2007, 09:16 PM
  3. DX9 Not Displaying Bitmaps
    By Sentral in forum Game Programming
    Replies: 9
    Last Post: 01-31-2006, 05:35 AM
  4. MFC: Multiple clicks shows multiple bitmaps - how?
    By BrianK in forum Windows Programming
    Replies: 0
    Last Post: 06-20-2004, 07:25 PM
  5. Transparent Bitmap - inserting into richeditctrl
    By LuckY in forum Windows Programming
    Replies: 1
    Last Post: 08-06-2003, 12:20 PM