Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
273 views
in Technique[技术] by (71.8m points)

c++ - AlphaBlend generating incorrect colors

I've managed to avoid Windows GDI for decades, and now I'm paying the price. The following C++ code does not result in the correct colors. It's just supposed to white-fill a window and then alpha blend a single bitmap. All of the alpha is per-pixel alpha in the bitmap.

// Create a memory DC
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmMem = CreateCompatibleBitmap(hdc, cxWnd, cyWnd);
SelectObject(hdcMem, hbmMem);

// White-fill the BG
FillRect(hdcMem, &rectWnd, static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)));

// Alpha blend the bitmap into the memory DC
HDC hdcSrc = CreateCompatibleDC(hdcMem);
HBITMAP hbmOld = static_cast<HBITMAP>(SelectObject(hdcSrc, hbm));
BLENDFUNCTION bfn = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
AlphaBlend(hdcMem, x, y, cxBmp, cyBmp, hdcSrc, 0, 0, cxBmp, cyBmp, bfn);
SelectObject(hdcSrc, hbmOld);
DeleteDC(hdcSrc);

// Blit the memory DC to the screen
BitBlt(hdc, 0, 0, cxWnd, cyWnd, hdcMem, 0, 0, SRCCOPY);

I've verified that all the variable values are correct and that the bitmap in hbm has the correct pixel colors and alphas.

The result shows many wrong colors, e.g., a blue pixel with low alpha should be pale blue but instead is dark red. Pixels with high alpha are much closer to what they should be.

Any help appreciated. TIA.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The answer, from hints in the comments: Each color channel in each pixel must be premultiplied by the alpha before blending.

get DIB bits
for each pixel
  r = r * alpha / 255
  g = g * alpha / 255
  b = b * alpha / 255
set DIB bits

MS does not make this stuff easy to find. There's not a hint of it in the only alpha blending sample I could find:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd183353(v=vs.85).aspx


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...