Drawing a bitmap transparently


Drawing a bitmap transparently means that only those pixels that are not the designated transparent color are drawn onto the target device context. The pixels on the target device context that correspond to a transparent pixel in the source is left unchanged. Any color may be designated as being transparent. If you are drawing the bitmap from scratch you want to choose a background color that will not be used in the foreground. This background color can then be treated as the transparent color.

Here's what happens in the function. Besides getting the handle to the destination device context, the function creates three more device context. The tempDC is used to select the source bitmap into. This is used to copy the image into the second device context - the memDC. The third device context is the maskDC. The maskDC contains a monochrome bitmap. The maskDC is instrumental in allowing us to copy the foreground pixels only.

If the palette handle passed into the function is not null and if the destination device context supports palettes, we select the palette into the destination DC. Note that the last argument to the SelectPalette() function is FALSE. This indicates that the palette should be a foreground palette. That is, the exact colors in the palette should be displayed. If this argument were TRUE, then the colors in the logical palette would be mapped to the closest colors already in the physical palette. The call to RealizePalette() maps the palette entries to the system palette. We also select the palette into the memDC so that when the bitmap is copied into it, the colors are mapped properly.

We next create the mask bitmap from the source bitmap image. When we use BitBlt() to copy a color bitmap to a monochrome bitmap then all the pixels that are of the background color are copied as white pixels. All the remaining pixels (that is pixels that are not of the background color) are copied as black pixels. You will note that we call the SetBkColor() for the memDC with the transparent color.

Once we have the mask bitmap, we modify both the source image and the destination image so that we can then combine them to get the final image. Imagine that we have two sheets of paper, one with the image that is to be drawn over and the other with the bitmap image that is to be drawn transparently over the first image. What we do is take the second sheet with the bitmap image and cut out all the parts that contain the background color. We then take the first sheet and cut out all parts of it that correspond to the foreground of the bitmap image. We can now combine the two sheets to get a complete sheet without any overlap and get the final image.

This is what we do with the images in the device contexts. We take the memDC and copy the image in maskDC in such a way that all the background pixels are turned into black pixels - the equivalent of cutting these pixels away. Let's analyze how we do this. We first set the background color in memDC to black and we set the foreground (text color) to white. We then use the BitBlt() function to combine each pixel in the mask to the corresponding pixel in the image in memDC using the raster AND operation. Whenever the BitBlt() function encounters a background pixel (white) in maskDC, it uses the background color in memDC (black) and does a raster AND operation with the corresponding pixel in memDC. The result of a raster AND operation involving the black color is always black. Similarly, whenever the BitBlt() function encounters a foreground color (black) in the maskDC, is uses the text color in memDC (white) and combines it with the raster AND operation with the corresponding pixel in memDC. The result of a raster AND operation involving white and any other color is always the other color. That is, the destination pixel remains unchanged.

We execute a similar operation on the image in the destination device context. Only, this time we change all the pixels corresponding to the foreground color in the mask to white. We can now combine the two images using the raster operation SRCPAINT. The result of the SRCPAINT operation is such that any colored pixel combined with a black pixel results in the same colored pixel.

// TransparentBlt	- Copies a bitmap transparently onto the destination DC
// hdcDest		- Handle to destination device context 
// nXDest		- x-coordinate of destination rectangle's upper-left corner 
// nYDest		- y-coordinate of destination rectangle's upper-left corner 
// nWidth		- Width of destination rectangle 
// nHeight		- height of destination rectangle 
// hBitmap		- Handle of the source bitmap
// nXSrc		- x-coordinate of source rectangle's upper-left corner 
// nYSrc		- y-coordinate of source rectangle's upper-left corner 
// colorTransparent	- The transparent color
// hPal			- Logical palette to be used with bitmap. Can be NULL

void TransparentBlt( HDC hdcDest, int nXDest, int nYDest, int nWidth, 
			int nHeight, HBITMAP hBitmap, int nXSrc, int nYSrc,
			COLORREF colorTransparent, HPALETTE hPal )
{
	CDC dc, memDC, maskDC, tempDC;
	dc.Attach( hdcDest );
	maskDC.CreateCompatibleDC(&dc);
	CBitmap maskBitmap;
	
	//add these to store return of SelectObject() calls
	CBitmap* pOldMemBmp = NULL;
	CBitmap* pOldMaskBmp = NULL;
	HBITMAP hOldTempBmp = NULL;
	
	memDC.CreateCompatibleDC(&dc);
	tempDC.CreateCompatibleDC(&dc);
	CBitmap bmpImage;
	bmpImage.CreateCompatibleBitmap( &dc, nWidth, nHeight );
	pOldMemBmp = memDC.SelectObject( &bmpImage );
	
	// Select and realize the palette
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && hPal )
	{
		::SelectPalette( dc, hPal, FALSE );
		dc.RealizePalette();
		
		::SelectPalette( memDC, hPal, FALSE );
	}
	
	hOldTempBmp = (HBITMAP) ::SelectObject( tempDC.m_hDC, hBitmap );
	
	memDC.BitBlt( 0,0,nWidth, nHeight, &tempDC, nXSrc, nYSrc, SRCCOPY );
	
	// Create monochrome bitmap for the mask
	maskBitmap.CreateBitmap( nWidth, nHeight, 1, 1, NULL );
	pOldMaskBmp = maskDC.SelectObject( &maskBitmap );
	memDC.SetBkColor( colorTransparent );
	
	// Create the mask from the memory DC
	maskDC.BitBlt( 0, 0, nWidth, nHeight, &memDC, 
		0, 0, SRCCOPY );
	
	// Set the background in memDC to black. Using SRCPAINT with black 
	// and any other color results in the other color, thus making 
	// black the transparent color
	memDC.SetBkColor(RGB(0,0,0));
	memDC.SetTextColor(RGB(255,255,255));
	memDC.BitBlt(0, 0, nWidth, nHeight, &maskDC, 0, 0, SRCAND);
	
	// Set the foreground to black. See comment above.
	dc.SetBkColor(RGB(255,255,255));
	dc.SetTextColor(RGB(0,0,0));
	dc.BitBlt(nXDest, nYDest, nWidth, nHeight, &maskDC, 0, 0, SRCAND);
	
	// Combine the foreground with the background
	dc.BitBlt(nXDest, nYDest, nWidth, nHeight, &memDC, 
		0, 0, SRCPAINT);
	
	
	if (hOldTempBmp)
		::SelectObject( tempDC.m_hDC, hOldTempBmp);
	if (pOldMaskBmp)
		maskDC.SelectObject( pOldMaskBmp );
	if (pOldMemBmp)
		memDC.SelectObject( pOldMemBmp );
	
	dc.Detach();
}



Comments

  • Wholesale Oakley Hijinx 90% off sale

    Posted by mzultzdrv on 06/27/2013 04:57pm

    Womens Oakley Sunglasses ,Everyone has many selections, inside the recent social, Oakley, sunglasses best style to cause you to comfortable, relaxed impression, transform your romantic and charming appearance. Oakley sunglasses, black frame clear lens for affordable Oakley sunglasses design in Asia greater than all of those other ways is an effective example. Fake Oakleys ,You can use different greens, brown, tortoise and lavender. These Oakley sunglasses features manually create the framework to make sure they believe you want. Every second of the fashion-savvy people, you'll discover that there must be a set of Oakley sunglasses, usually the most popular and affordable cheap Oakley sunglasses have been provided a brand new specification of the glasses. OakLey Hijinx ,Continuous development, in order that an excellent posture, the comparison in another article. The rays of the sun, including ultraviolet radiation, and similar to the sun. You are able to wear glasses a bold fashion statement, for those who have been completely increasingly common disturbed and located a little else to bother with. Know used sheet metal sunglasses, for time could be slightly deformed, that is a normal phenomenon. Dealer Executive to adjust to. Brown lenses filter out blue light, in the case of air pollution or fog, can improve visual contrast in the obvious effect of wearing a plus. The way lovers also offers an entry to the clothes customized according to the number of the specific features to make sure that they are a perfect match the type of clothing. Oakley shades of excellent quality (specially the "surround variety), major safety and solar powered energy, ultraviolet illumination for the eye to offer you, these are suitable for people of any age. Oakley is that you simply expect through the world of performance innovation producing unparalleled technology products, it uses a unique interchangeable lens design, and that means you have the product from the optical properties on the match along with the environment. Women may decide to glance several very eye-catching within the general population, women cheap Oakley women's sunglasses to verify the acquisition in the U.S. flag. Oakley sunglasses they HDO (high-definition optical) is well know, and in addition they keep using this breakthrough technology within their design. Do you really need prescription sunglasses or just want quality accessories to make sure you receive everything you pay for, you'll find individuals who offer online Oakley suppliers.

    Reply
  • How do I set background colund white where foreground has a line of definite width and length

    Posted by Legacy on 07/16/2003 12:00am

    Originally posted by: deepthi

    How do I set background colour black and foreground colour towhite where foreground has a line of definite width and length

    Reply
  • Serializing the bitmap

    Posted by Legacy on 11/21/2002 12:00am

    Originally posted by: srinivasan

    How to reload the bitmap using serialization.
    

    Reply
  • Where is the article:TransparentBlt using only two BLT operations - m.chung (1998/12/18)?

    Posted by Legacy on 08/09/2002 12:00am

    Originally posted by: Hector

    Where is the article: TransparentBlt using only two BLT operations - m.chung (1998/12/18)?

    I need it. Thanks

    Reply
  • Excellent! Works great.

    Posted by Legacy on 06/14/2002 12:00am

    Originally posted by: J.Reichard

    Thanks a million!

    Reply
  • How to add transparent bitmap into header control for list view

    Posted by Legacy on 04/18/2002 12:00am

    Originally posted by: Tao Zhou

    Thanks

    Reply
  • Easier with image-list

    Posted by Legacy on 05/16/2001 12:00am

    Originally posted by: Stephan Brenner

    First I tried your function, but I had problems when printing. So I wrote my own short function using an image-list for drawing the bitmap transparently.

    void TransparentBlt(CDC* pDC, HBITMAP hBitmap, CPoint ptLocation)
    {
    CBitmap* pBitmap = CBitmap::FromHandle(hBitmap);

    // Get size of bitmap
    BITMAP bmpInfo;
    CSize bitSize;
    pBitmap->GetBitmap(&bmpInfo);
    bitSize = CSize(bmpInfo.bmWidth, bmpInfo.bmHeight);

    // Prepare ImageList
    CImageList imageList;
    imageList.Create(bitSize.cx, bitSize.cy, ILC_COLOR24|ILC_MASK, 1, 1);
    imageList.Add(pBitmap, 0xFFFFFF); // Transparent color: WHITE

    // Draw imagelist transparently
    imageList.DrawIndirect(pDC, 0, ptLocation, bitSize, CPoint(0, 0));
    }

    Reply
  • This function does no work with resource(system color) bitmaps.

    Posted by Legacy on 12/04/2000 12:00am

    Originally posted by: Andrey Zwyagilskii

    I spent many time trying to force this function work. But have no result. I use CImageList for this purpose. It is 2 lines of code need to draw system color bitmap transparently:
    m_ImgLst.Create( IDB_BITMAP, 16, 1, RGB(0,255,255) );
    m_ImgLst.Draw(pDC,0,CPoint(x0,y0),ILD_TRANSPARENT);

    This method works perfectly to all images.

    Reply
  • All black output ?

    Posted by Legacy on 05/17/2000 12:00am

    Originally posted by: Morten Andersen

    I tried your routine, but instead of getting a transparent blit, I got an all black output. The bitmap I'm copying from is 256 colors, and the bitmap I'm blitting to is 16M colors. Can that have anything to do with it ?

    Please tell me what went wrong, and how I can fix it.

    - Morten Andersen

    Reply
  • Help me in drawing a bitmap in Dialog based Projects.

    Posted by Legacy on 04/12/2000 12:00am

    Originally posted by: Ren

    Hi, 
    
    

    I am trying to place a bitmap on my dialog based MFC project. I have used double buffering in OnInitDialog() and OnPaint(), but It didn't work to draw, bitmaps, even to SetBkColor(). Any help is appriciated.

    Ren.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • In this on-demand webcast, Oracle ACE and Toad Product Architect Bert Scalzo discusses 10 powerful and hidden features in Toad® that help increase your productivity and DB performance. Watch this webcast today.

  • All businesses have a core set of applications that are critical to successful growth. These applications require a higher level of availability than other applications and services in the organization. There is a trade-off, however, to increasing application availability through traditional high-availability clustering. Businesses can see costs surge in terms of additional hardware and clustering software/support, as well as additional costs and complexities due to increased operational management …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds