透明度叠加算法:如何计算半透明像素叠加到另一个像素上的实际可见像素值(附 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 的实现)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

人工智能

人工智能

李开复、王咏刚 / 文化发展出版社 / 2017-5-10 / CNY 55.00

人工智能已经来了,它就在我们身边,几乎无处不在。 人工智能技术正在彻底改变人类的认知,重建人机相互协作的关系。史无前例的自动驾驶正在重构我们头脑中的出行地图和人类生活图景,今天的人工智能技术也正在翻译、写作、绘画等人文和艺术领域进行大胆的尝试。 我们真的知道什么是人工智能吗? 我们真的准备好与人工智能共同发展了吗? 我们该如何在心理上将人和机器摆在正确的位置? 我们该......一起来看看 《人工智能》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具