Skip to main content
GameDev.net gamedev.net
🔒 Locked

How to make a portion of a bitmap transparent using GDI+?

Started by HellzGod May 31, 2008 at 7:09 AM 0 replies 7.2k views
Original Post
HellzGod
HellzGod
Hi, I have a handle to a 32 bit bitmap. I want to make some rectangles in the bitmap transparent and the rest opaque. My question is does gdi+ provide an easy way to do that? Or should I use SetDIBits() / CreateDIBSection and manipulate every pixel? Thanks, M
Koobazaur
Koobazaur
Not exactly what you're looking for, but may be useful, here's some of my old code for drawing transpernt bitmaps. I used a bitmap + a mask to do it, though:

//=============== TBitmap ======================================================// Draws a transparent bitmap to the back buffer, using// a passed in mask. White is transparent.// uses SRCAND and SRCPAINT bit blit operators// HBITMAP bmp - bitmap we want to draw// HBITMAP mask - the mask we want to use for the blit// int x  - the x coordinate at which we want to draw// int y  - the y coordinate at which we want to draw// int wx - width of the bitmap rectangle which we want to draw// int wy - height of the bitmap rectangle which we want to draw// int dx - the x coordinate of the source bitmap from which we want to start drawing// int dy - the y coordinate of the source bitmap from which we want to start drawing//==============================================================================void KScrBuffer::TBitmap(HBITMAP bmp,HBITMAP mask, int x, int y, int wx, int wy,int dx, int dy)//displays transparent bitmap to backbuffer{                                                                                            //using a pre-made maks bitmap                                                                    //if the width and height of the draw rectangle are 0 (default) then set them //to our client rectangle (i.e. we want to draw as much of the bitmap as fits //on the screen)    if(wx==0) 	wx=ClRect.right; if(wy==0)   wy=ClRect.bottom; //The following code blits the mask to the screen with AND (so that only the  //black portions are blitted), then blits the bitmap with PAINT (so that the  //bitmap gets pained over only the previously blitted black portions) OldBitmap = (HBITMAP)SelectObject(HDCbitmap, mask);            //select mask BitBlt(HDCback, x, y, wx, wy, HDCbitmap, dx, dy, SRCAND);   //blit with AND SelectObject(HDCbitmap, bmp);                               //select bitmap BitBlt(HDCback, x, y, wx, wy, HDCbitmap, dx, dy, SRCPAINT); //blit with PAINT //select old bitmap to HDC SelectObject(HDCbitmap, OldBitmap);}


And here's two functions, the first creates mask for a bitmap and the second modifies the bitmap so that it can be used with the mask to display transparency using the function above.

//=============== CreateBitmapMask ==============================================// Creates a mask for a given bitmap. White is transparent, black is solid// HBITMAP hbmColour - the bitmap we want to create the mask for// COLORREF crTransparent  - the color we should consider as transparent in the //                           bitmap (default black)//============================================================================== HBITMAP CreateBitmapMask(HBITMAP bmp, COLORREF crTransparent){												    HBITMAP mask;		 //our mask bitmap																			    HDC hdcMem, hdcMem2; //two temporary HDCs we will use for blitting    BITMAP rawBitmap;    //raw bitmap information    // Create monochrome (1 bit) mask bitmap    GetObject(bmp, sizeof(BITMAP), &rawBitmap);    mask = CreateBitmap(rawBitmap.bmWidth, rawBitmap.bmHeight, 1, 1, NULL);    // Create HDCs that are compatible with the display driver    hdcMem = CreateCompatibleDC(0);    hdcMem2 = CreateCompatibleDC(0);    //select the bitmap and mask to the HDCs    SelectObject(hdcMem, bmp);    SelectObject(hdcMem2, mask);    // Set the background color of the bitmap to the color    // we want to be transparent.    SetBkColor(hdcMem, crTransparent);    // Copy the bits from the color image to the B+W mask... everything    // with the background color ends up white while everythig else ends up    // black...Just what we wanted.    BitBlt(hdcMem2, 0, 0, rawBitmap.bmWidth, rawBitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);    // Clean up.    DeleteDC(hdcMem);    DeleteDC(hdcMem2);        //return the mask    return mask;}//=============== MakeTransparent =============================================// Adjusts a bitmap so that it can be used for transparent // drawing using a mask. // HBITMAP * bmp - the bitmap we want to adjust// UINT TransparentColor - the color we want to make transparent// RETURN: the created mask bitmap//==============================================================================   void MakeTransparent(HBITMAP* bmp, UINT TransparentColor)//makes a bitmap transparent{    HDC hdcMem, hdcMem2; //two temporary HDCs we will use for blitting    HBITMAP hbmMask;     //a mask for our bitmap    BITMAP rawBitmap;    //raw bitmap information    // Create monochrome (1 bit) mask bitmap.    GetObject(bmp, sizeof(BITMAP), &rawBitmap);    hbmMask = CreateBitmap(rawBitmap.bmWidth, rawBitmap.bmHeight, 1, 1, NULL);    // Create HDCs that are compatible with the display driver    hdcMem = CreateCompatibleDC(0);    hdcMem2 = CreateCompatibleDC(0);    //select the bitmap and mask to the HDCs    SelectObject(hdcMem, bmp);    SelectObject(hdcMem2, hbmMask);    // Set the background color of the bitmap to the color    // we want to be transparent.    SetBkColor(hdcMem, TransparentColor);    // Copy the bits from the color image to the B+W mask... everything    // with the background color ends up white while everythig else ends up    // black...Just what we wanted.    BitBlt(hdcMem2, 0, 0, rawBitmap.bmWidth, rawBitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);    // Take our new mask and use it to turn the transparent color in our    // original bitmap to black so the transparency effect will    // work right.    BitBlt(hdcMem, 0, 0, rawBitmap.bmWidth, rawBitmap.bmHeight, hdcMem2, 0, 0, SRCINVERT);    // Clean up.    DeleteDC(hdcMem);    DeleteDC(hdcMem2);    DeleteObject(hbmMask);}


So you would do something like:

HBITMAP MyBitmap = Load(...); //our bitmap where RGB(100,0,100) denotes transparency)HBITMAP Mask = CreateBitmapMask(MyBitmap, RGB(100,0,100)); ScreenBuffer.MakeTransparent(&Mybitmap, RGB(100,0,100));ScreenBuffer.TBitmap(MyBitmap, Mask, 0,0);


This code is pretty old and part of my ScreenBuffer object but hopefully will give you some ideas.

There also is a TransparentBlit function, but AFAIK, it leaks memory.
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.