Wednesday, 1 December 2010

Why's my Alpha blend not working!!

That was what I was saying as I do an AlphaBlend() of a 32 bit bitmap nicely saved in Photoshop, the result was a bitmap with white as the 'background' instead of a nice transparent edge.

I've seen this before and moving between Desktop and WinCE I seem to have slightly different results with Alpha blending and image factory stuff. Anyhow I found a few people mentioning that you need to pre-multiply any alpha per pixel before using the Alpha blend (which has an alpha on the image as well). Sceptical but tried it and hey presto my bitmaps now render perfectly.

Here is what I do in Win32:

HBITMAP hbmp = CreateDIBSection(hdcScreen, lpbi, DIB_RGB_COLORS, &pvImageBits, NULL, 0);

const UINT cbImage = cbStride * height;
if (FAILED(ipBitmap->CopyPixels(NULL, cbStride, cbImage, static_cast<BYTE *>(pvImageBits))))
{
// couldn't extract image; delete HBITMAP
DeleteObject(hbmp);
hbmp = NULL;
}

// Pre multiply RGB on alpha channels else alpha blit won't work!
//
if (lpbi->bmiHeader.biBitCount == 32)
{
BYTE* linePtr = (BYTE*)pvImageBits;
for(int y=0;y<height;y++)
{
BYTE* ptr = linePtr;

for(int x=0;x<width;x++)
{
BYTE alpha = *(ptr+3);
*(ptr+0)=(*(ptr+0) * alpha) / 255;
*(ptr+1)=(*(ptr+1) * alpha) / 255;
*(ptr+2)=(*(ptr+2) * alpha) / 255;
ptr+=4;
}

linePtr += cbStride;
}
}
Then just AlphaBlend on my bitmap...perfect, but why doesn't AlphaBlend handle the 32 bit bitmaps anyhow that's what I don't understand.... !