Click here to Skip to main content
13,197,271 members (59,763 online)
Rate this:
Please Sign up or sign in to vote.
See more:
I use to draw device-independent bitmaps (DIBs) to the screen by means of either SetDIBitsToDevice (true size) or StretchDIBits (with zoom).

These functions move pixel data from a memory buffer directly to screen. [This operation is not the same as copying from one DC (Device Context) to another DC nor from a DDB (Device Dependent Bitmap) to another.]

So far so good. Works well with the image depths I am using (biBitCount = 8, 24 or 32).

Now I want to do partial drawing, as if parts of the image were transparent. In other words, attach an alpha value to every pixel. I can satisfy myself with binary values (fully opaque or fully transparent), but plain alpha is good too.

I have the option of reading the background pixels from screen and doing the blend myself, but this solution doesn't look attractive to me, because it involves costly reads, plus the need to convert to 24 bits because the background of a Window is in color.

So I am looking for efficient ways to achieve this effect. I expected to find BlendDIBitsToDevice or StretchBlendDIBits entries or similar, but it seems I need to roll up my sleeves.

Any suggestion ?
Posted 21-Feb-13 22:47pm
Updated 4-Jun-13 9:29am

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

The solution is to use the AlphaBlend function. The latter requires two things: on one hand a source device context, and on the other hand a source bitmap, which must be selected into it (don't ask me why).

The device context is created as a memory DC which is compatible with the display DC. It is obtained by means of CreateCompatibleDC.

The bitmap is generated as a so called DIB Section, via CreateDIBSection.

Last but not least, you have to know that premultiplied Alpha is required, meaning that all three Red, Green, Blue components must be multiplied by Alpha (and scaled) before blitting. Here is a snippet.
		// Initialize the bitmap info structure
		struct tagBITMAPINFO 
			BITMAPV4HEADER bmiHeader; 
			RGBQUAD bmiColors[256]; 
		} BufferInfo;
		BufferInfo.bmiHeader.bV4Size= sizeof(BITMAPV4HEADER); 
		BufferInfo.bmiHeader.bV4Width= Width; 
		BufferInfo.bmiHeader.bV4Height= Height; 
		BufferInfo.bmiHeader.bV4Planes= 1; 
		BufferInfo.bmiHeader.bV4BitCount= 32;
		BufferInfo.bmiHeader.bV4V4Compression= BI_BITFIELDS;
		BufferInfo.bmiHeader.bV4SizeImage= 0;
		BufferInfo.bmiHeader.bV4ClrUsed= 0;
		BufferInfo.bmiHeader.bV4ClrImportant= 0; 
		BufferInfo.bmiHeader.bV4AlphaMask= 0xff000000;
		BufferInfo.bmiHeader.bV4RedMask=   0x00ff0000;
		BufferInfo.bmiHeader.bV4GreenMask= 0x0000ff00;
		BufferInfo.bmiHeader.bV4BlueMask=  0x000000ff;
		BufferInfo.bmiHeader.bV4CSType= 0;
		// Create a compatible device context
		HDC hMemoryDC= CreateCompatibleDC(hDC);
		// Create a DIB section and select it
		byte* Section;
		HBITMAP hBitMap = CreateDIBSection(MemoryDC, (BITMAPINFO*)&BufferInfo, DIB_RGB_COLORS, (void**)&Section, NULL, 0x0);
		HGDIOBJ Save= SelectObject(hMemoryDC, hBitMap);
		// Premultiply by alpha
		for (int y= 0; y < Height; y++)
			for (int x= 0; x < Width; x++)
				RgbaPixel P= *(RgbaPixel*)&SrcBuffer[y * SrcPitch + 4 * x];
				int Q= P.Alpha * 33025; // 2^31 / 255^2
				P.Red=   (P.Red   * Q) >> 23;
				P.Green= (P.Green * Q) >> 23;
				P.Blue=  (P.Blue  * Q) >> 23;
				*(RgbaPixel*)&Section[y * SrcPitch + 4 * x]= P;
		// Blending function (required by AlphaBlend)
		Blend.BlendOp = AC_SRC_OVER;
		Blend.BlendFlags = 0;
		Blend.AlphaFormat = AC_SRC_ALPHA; 
		Blend.SourceConstantAlpha = 0xff; 
		// Blit with blending
			hDC, 0, 0, (int)(Width * Zoom), (int)(Height * Zoom), 
			hMemoryDC, 0, 0, Width, Height, 
		SelectObject(hMemoryDC, Save);

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web03 | 2.8.171020.1 | Last Updated 4 Jun 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100