【问题标题】:Understanding AlphaBlending in Windows了解 Windows 中的 AlphaBlending
【发布时间】:2016-01-12 06:18:10
【问题描述】:

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

我正在阅读文档,结果发现对于混合,在我想使用每像素值的情况下,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 以这种方式进行混合?我在这里错过了什么?

我用来绘制分层窗口的代码的 sn-p:

            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);

【问题讨论】:

    标签: c++ winapi alphablending


    【解决方案1】:

    来自documentation

    请注意,API 使用预乘 alpha,这意味着红色、 位图中的绿色和蓝色通道值必须与 Alpha 通道值。例如,如果 Alpha 通道值为 x, 红色、绿色和蓝色通道必须乘以 x 并除以 通话前的 0xff。

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

    【讨论】:

    • 啊。预乘法现在有意义了。但他们为什么要这样保留它呢?
    • 我写的可能很快。再次从文档中:“它使用预乘 alpha 是有充分理由的。每次对每个像素都将源颜色乘以源 alpha 是效率不高的。它只需要执行一次,因为颜色和 alpha值是相关的。它通常在创建图像期间完成(例如 PNG,使用预乘 alpha),并且每次绘制都会为每个像素节省非常昂贵的乘法。"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-05
    • 2018-06-08
    • 2013-04-06
    • 1970-01-01
    • 2010-12-21
    • 2017-09-16
    相关资源
    最近更新 更多