了解 Windows 中的 AlphaBlending

Understanding AlphaBlending in Windows

我有一个 32bpp 位图图像,它有一个 alpha 通道,值范围为 0-255。我正在尝试使用 win32 API 在 window 中显示它(附加了我用来显示的代码片段)。

我正在阅读文档,结果发现对于混合,在我想使用每像素值的情况下,windows 使用以下公式:

Dst.Red     = Src.Red   + (1 - Src.Alpha) * Dst.Red
Dst.Green   = Src.Green + (1 - Src.Alpha) * Dst.Green
Dst.Blue    = Src.Blue  + (1 - Src.Alpha) * Dst.Blue

这很奇怪。我原以为它会使用:

Dst.Red     =  Src.Alpha*Src.Red    + (1 - Src.Alpha) * Dst.Red
Dst.Green   =  Src.Alpha*Src.Green  + (1 - Src.Alpha) * Dst.Green
Dst.Blue    =  Src.Alpha*Src.Blue   + (1 - Src.Alpha) * Dst.Blue

因为这就是产生叠加效果(半透明)的原因。

我的预期是否正确?如果是,为什么 windows 以这种方式进行混合?我在这里错过了什么?

我用来绘制分层的代码片段 Window:

            bf.BlendOp = AC_SRC_OVER;
            bf.BlendFlags = 0;
            bf.SourceConstantAlpha = 255;  
            bf.AlphaFormat = AC_SRC_ALPHA;              
            POINT ptOrigin = { 0, 0 };
            SIZE windowSize = { 300, 300 };

            POINT ptZero = { 0, 0 };

            UpdateLayeredWindow(m_sThis->m_hWnd, dc, &ptOrigin, &windowSize,
                hdc, &ptZero, RGB(255, 255, 255), &bf, ULW_ALPHA);

来自documentation

Note that the APIs use premultiplied alpha, which means that the red, green and blue channel values in the bitmap must be premultiplied with the alpha channel value. For example, if the alpha channel value is x, the red, green and blue channels must be multiplied by x and divided by 0xff prior to the call.

所以,你是对的,但你之前必须手工完成。