Title: Alpha Blending a Bitmap
Question: Using AlphaBlend function in Delphi
Answer:
Alpha blending is used to display an alpha bitmap, which is a bitmap that has transparent or semi-transparent pixels.
In addition to a red, green, and blue color channel, each pixel in an alpha bitmap has a transparency component known as its alpha channel. The alpha channel typically contains as many bits as a color channel. For example, an 8-bit alpha channel can represent 256 levels of transparency, from 0 (the entire bitmap is transparent) to 255 (the entire bitmap is opaque). Alpha blending mechanisms are invoked by calling AlphaBlend function. The AlphaBlend function displays bitmaps that have transparent or semitransparent pixels. It is not supported on Microsoft Windows 95 or on versions of Microsoft Windows NT prior to Microsoft Windows 2000.
The following code sample divides a window into three horizontal areas. Then it draws an alpha-blended bitmap in each of the window areas.
const
AC_SRC_ALPHA = $1;
procedure DrawAlphaBlend (hWnd : HWND; hdcwnd : HDC);
var
Ahdc : HDC; // handle of the DC we will create
bf : BLENDFUNCTION; // structure for alpha blending
Ahbitmap : HBITMAP; // bitmap handle
bmi : BITMAPINFO; // bitmap header
pvBits : pointer; // pointer to DIB section
ulWindowWidth,
ulWindowHeight : ULONG; // window width/height
ulBitmapWidth,
ulBitmapHeight : ULONG; // bitmap width/height
rt : TRect; // used for getting window dimensions
begin
// get window dimensions
GetClientRect(hWnd, rt);
// calculate window width/height
ulWindowWidth := rt.right - rt.left;
ulWindowHeight := rt.bottom - rt.top;
// make sure we have at least some window size
if ((ulWindowWidth = 0 ) and (ulWindowHeight=0)) then
exit;
// divide the window into 3 horizontal areas
ulWindowHeight := trunc(ulWindowHeight / 3);
// create a DC for our bitmap -- the source DC for AlphaBlend
Ahdc := CreateCompatibleDC(hdcwnd);
// zero the memory for the bitmap info
ZeroMemory(@bmi, sizeof(BITMAPINFO));
// setup bitmap info
bmi.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth := trunc(ulWindowWidth - (ulWindowWidth/5)*2);
ulBitmapWidth := trunc(ulWindowWidth - (ulWindowWidth/5)*2);
bmi.bmiHeader.biHeight := trunc(ulWindowHeight - (ulWindowHeight/5)*2);
ulBitmapHeight := trunc(ulWindowHeight - (ulWindowHeight/5)*2);
bmi.bmiHeader.biPlanes := 1;
bmi.bmiHeader.biBitCount := 32; // four 8-bit components
bmi.bmiHeader.biCompression := BI_RGB;
bmi.bmiHeader.biSizeImage := ulBitmapWidth * ulBitmapHeight * 4;
// create our DIB section and select the bitmap into the dc
Ahbitmap := CreateDIBSection(Ahdc, bmi, DIB_RGB_COLORS, pvBits, 0, 0);
SelectObject(Ahdc, Ahbitmap);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.SourceConstantAlpha := $7f; // half of 0xff = 50% transparency
bf.AlphaFormat := 0; // ignore source alpha channel
AlphaBlend(hdcwnd, trunc(ulWindowWidth/5), trunc(ulWindowHeight/5),
ulBitmapWidth, ulBitmapHeight,
Ahdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.AlphaFormat := AC_SRC_ALPHA; // use source alpha
bf.SourceConstantAlpha := $ff; // opaque (disable constant alpha)
AlphaBlend(hdcwnd, trunc(ulWindowWidth/5),
trunc(ulWindowHeight/5+ulWindowHeight), ulBitmapWidth, ulBitmapHeight,
Ahdc, 0, 0, ulBitmapWidth, ulBitmapHeight, bf);
bf.BlendOp := AC_SRC_OVER;
bf.BlendFlags := 0;
bf.AlphaFormat := 0;
bf.SourceConstantAlpha := $3A;
AlphaBlend(hdcwnd, trunc(ulWindowWidth/5),
trunc(ulWindowHeight/5+2*ulWindowHeight), ulBitmapWidth,
ulBitmapHeight, Ahdc, 0, 0, ulBitmapWidth,
ulBitmapHeight, bf);
// do cleanup
DeleteObject(Ahbitmap);
DeleteDC(Ahdc);
end;