Home » Community » Forums » General Programming » How to make a portion of a bitmap transparent using GDI+?
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic


 Last Thread Next Thread 
 How to make a portion of a bitmap transparent using GDI+?
Post New Topic  Post Reply 
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

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

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.

 User Rating: 1073   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: