透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)

栏目: ASP.NET · 发布时间: 5年前

内容简介:本文介绍透明度叠加算法(Alpha Blending Algorithm),并用 C#/WPF 的代码,以及像素着色器的代码 HLSL 来实现它。对于算法,我只是搬运工,可以随意搜索到。算法详情请查看:对于完全不透明的背景和带有透明度的前景,合并算法为:

本文介绍透明度叠加算法(Alpha Blending Algorithm),并用 C#/WPF 的代码,以及像素着色器的代码 HLSL 来实现它。

算法

对于算法,我只是搬运工,可以随意搜索到。算法详情请查看: Alpha compositing - Wikipedia

对于完全不透明的背景和带有透明度的前景,合并算法为:

float r = (foreground.r * alpha) + (background.r * (1.0 - alpha));

这是红色。然后绿色 g 和蓝色 b 通道进行一样的计算。最终合成图像的透明通道始终设置为 1。

在 C# 代码中实现

多数 UI 框架对于颜色值的处理都是用一个 byte 赛表单个通道的一个像素。于是计算会采用 0xff 即 255。

for (int i = 0; i + 4 < length; i = i + 4)
{
    var backB = background[i];
    var backG = background[i + 1];
    var backR = background[i + 2];
    var foreB = foreground[i];
    var foreG = foreground[i + 1];
    var foreR = foreground[i + 2];
    double alpha = foreground[i + 3];

    blue = 0;

    output[i] = (foreB * alpha) + (backB * (1.0 - alpha));
    output[i + 1] = (foreG * alpha) + (backG * (1.0 - alpha));
    output[i + 2] = (foreR * alpha) + (backR * (1.0 - alpha));
    output[i + 3] = 1.0;
}

这段代码当然是跑不起来的,因为是下面两篇博客的魔改代码。你需要阅读以下两篇博客了解如何在 WPF 中按像素修改图像,然后应用上面的透明度叠加代码。

话说,一般 UI 框架都自带有透明度叠加,为什么还要自己写一份呢?

当然是因为某些场景下我们无法使用到 UI 框架的透明度叠加特性的时候。例如使用 HLSL 编写像素着色器的一个实现。

下面使用像素着色器的实现是我曾经写过的一个特效的一个小部分,我把透明度叠加的部分单独摘取出来。

在像素着色器中实现

以下是 HLSL 代码的实现。Background 是从采样寄存器 0 取到的颜色采样,Foreground 是从采样寄存器 1 取到的颜色采样。

这里的计算中,背景是不带透明度的,而前景是带有透明度的。

/// <description>透明度叠加效果。</description>

sampler2D Background : register(s0);
sampler2D Foreground : register(s1);

float4 main(float2 uv : TEXCOORD) : COlOR
{
    float4 background = tex2D(Background, uv);
    float4 foreground = tex2D(Foreground, uv);
    float alpha = foreground.a;

    float r = (foreground.r * alpha) + (background.r * (1.0 - alpha));
    float g = (foreground.g * alpha) + (background.g * (1.0 - alpha));
    float b = (foreground.b * alpha) + (background.b * (1.0 - alpha));
    float a = 1.0;
    
    return float4(r, g, b, a);
}

透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)

如果要测试的图片都是不带透明度的,那么可以通过自己设一个透明度来模拟,传入透明度值 Alpha。

/// <description>透明度叠加效果。</description>

/// <type>Double</type>
/// <summary>采样 2 的叠加透明度。</summary>
/// <minValue>0.0</minValue>
/// <maxValue>1.0</maxValue>
/// <defaultValue>0.75</defaultValue>
float Alpha : register(C0);

sampler2D Background : register(s0);
sampler2D Foreground : register(s1);

float4 main(float2 uv : TEXCOORD) : COlOR
{
    float4 background = tex2D(Background, uv);
    float4 foreground = tex2D(Foreground, uv);
    float alpha = Alpha;

    float r = (foreground.r * alpha) + (background.r * (1.0 - alpha));
    float g = (foreground.g * alpha) + (background.g * (1.0 - alpha));
    float b = (foreground.b * alpha) + (background.b * (1.0 - alpha));
    float a = 1.0;
    
    return float4(r, g, b, a);
}

透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)

参考资料


以上所述就是小编给大家介绍的《透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 WPF 和 HLSL 的实现)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

具体数学(英文版第2版)

具体数学(英文版第2版)

[美] Ronald L. Graham、Donald E. Knuth、Oren Patashnik / 机械工业出版社 / 2002-8 / 49.00元

This book introduces the mathematics that supports advanced computer Programming and the analysis of algorithms. The primary aim of its well-known authors is to provide a solid and relevant base of ma......一起来看看 《具体数学(英文版第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具