龙空技术网

WPF 对应用程序进行灰度设置

opendotnet 182

前言:

目前咱们对“net framework35 sp1”都比较注意,同学们都想要学习一些“net framework35 sp1”的相关内容。那么小编同时在网上收集了一些对于“net framework35 sp1””的相关内容,希望小伙伴们能喜欢,各位老铁们快快来了解一下吧!

WPF 对应用程序进行灰度设置

控件名:GrayscaleEffect

作 者:WPFDevelopersOrg - 驚鏵

原文链接[1]:

简易源码[2]:

框架使用.NET4 至 .NET6;

Visual Studio 2019;

如果要实现灰度第一反是使用主题色更改,但是使用主题色需要重新配色比较慢,需 Effect 类派生以实现自定义位图效果,将使用ShaderEffect[3]进行更改灰度,从 ShaderEffect 类派生,以基于单个像素着色器实现自定义效果。

必须安装 .NET Framework 3.5 sp1 或更高版本才能正常工作。

需要安装DirectX SDK才能编译像素着色器效果。PixelShader[4]从预编译的高级着色语言 (HLSL) 字节代码加载 。定义表示效果参数和基于表面输入的 Brush 依赖属性。使用其中 RegisterPixelShaderSamplerProperty[5] 一个重载将这些输入与 HLSL 字节码中引用的寄存器号相关联。DirectX SDK[6]下载完成DirectX SDK安装完成。到安装目录下\Utilities\bin\x86执行以下命令,就会输出.ps文件。 Nuget 最新[7]Install-Package WPFDevelopers 1.1.0.2-preview3推荐使用Shazzam Shader Editor[8]进行编辑。

1) GrayscaleEffect.hlsl 代码如下:

HLSL 语言编写的像素着色器(Pixel Shader)代码:

对输入纹理进行采样得到每个像素的颜色值。

对每个像素的 R、G、B 值进行除以 A 值操作,以避免由于透明度不同而产生的颜色变化。

对每个像素的亮度进行调整,通过修改 brightness 参数来控制亮度。

将每个像素转换为灰度值。

对转换后的每个像素的 R、G、B 值进行进一步的处理,通过修改 factor 参数来控制调整效果。

返回调整后的像素颜色值。sampler2D:纹理采样器类型,用于从纹理中提取像素颜色信息。register():用于定义常量寄存器和纹理寄存器等,类似于 C++ 中的变量声明。float:浮点数类型。TEXCOORD:纹理坐标通道类型,表示 UV 坐标数据。COLOR:输出颜色类型,表示最终渲染的像素颜色信息。tex2D():采样纹理函数,用于从纹理中提取指定纹理坐标处的像素颜色值。sqrt():开方函数,用于计算灰度值。float4 result:表示颜色值的四维向量类型。result.r、result.g、result.b 和 result.a 分别表示 RGB 值和 Alpha 值。

sampler2D implicitInput : register(s0);

float factor : register(c0);

/// <summary>The brightness offset.</summary>

/// <minValue>-1</minValue>

/// <maxValue>1</maxValue>

/// <defaultValue>0</defaultValue>

float brightness : register(c1);

float4 main(float2 uv : TEXCOORD) : COLOR

{

float4 pixelColor = tex2D(implicitInput, uv);

pixelColor.rgb /= pixelColor.a;

// Apply brightness.

pixelColor.rgb += brightness;

// Return final pixel color.

pixelColor.rgb *= pixelColor.a;

float4 color = pixelColor;

float pr = .299;

float pg = .587;

float pb = .114;

float gray = sqrt(color.r * color.r * pr + color.g * color.g * pg + color.b * color.b * pb);

float4 result;

result.r = (color.r - gray) * factor + gray;

result.g = (color.g - gray) * factor + gray;

result.b = (color.b - gray) * factor + gray;

result.a = color.a;

return result;

}

2)执行命令 代码如下:

 fxc /T ps_2_0 /Fo E:\GrayscaleEffect\GrayscaleEffect.ps E:\GrayscaleEffect\GrayscaleEffect.hlsl

3)得到以下文件

4)新建GrayscaleEffect.cs 代码如下:

继承自ShaderEffect类,并使用像素着色器(Pixel Shader)来实现灰度效果。

在代码中定义了三个依赖属性,分别是Input、Factor和Brightness。其中:

Input属性表示作为着色器输入的Brush对象,可以是任何可用的画刷类型。

Factor属性表示灰度效果的因子。

Brightness属性表示效果的亮度。

通过在构造函数中创建像素着色器对象,并将其设置为PixelShader属性,以及使用UpdateShaderValue方法更新着色器属性的值,完成特效的初始化工作。

using System;

using System.Windows;

using System.Windows.Media;

using System.Windows.Media.Effects;

namespace WPFDevelopers

{

public class GrayscaleEffect : ShaderEffect

{

/// <summary>

/// Identifies the Input property.

/// </summary>

public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty("Input", typeof(GrayscaleEffect), 0);

/// <summary>

/// Identifies the Factor property.

/// </summary>

public static readonly DependencyProperty FactorProperty = DependencyProperty.Register("Factor", typeof(double), typeof(GrayscaleEffect), new UIPropertyMetadata(0D, PixelShaderConstantCallback(0)));

/// <summary>

/// Identifies the Brightness property.

/// </summary>

public static readonly DependencyProperty BrightnessProperty = DependencyProperty.Register("Brightness", typeof(double), typeof(GrayscaleEffect), new UIPropertyMetadata(0D, PixelShaderConstantCallback(1)));

/// <summary>

/// Creates a new instance of the <see cref="GrayscaleEffect"/> class.

/// </summary>

public GrayscaleEffect()

{

var pixelShader = new PixelShader();

pixelShader.UriSource = new Uri("WPFDevelopers;component/Effects/GrayscaleEffect.ps", UriKind.Relative);

PixelShader = pixelShader;

UpdateShaderValue(InputProperty);

UpdateShaderValue(FactorProperty);

UpdateShaderValue(BrightnessProperty);

}

/// <summary>

/// Gets or sets the <see cref="Brush"/> used as input for the shader.

/// </summary>

public Brush Input

{

get => ((Brush)(GetValue(InputProperty)));

set => SetValue(InputProperty, value);

}

/// <summary>

/// Gets or sets the factor used in the shader.

/// </summary>

public double Factor

{

get => ((double)(GetValue(FactorProperty)));

set => SetValue(FactorProperty, value);

}

/// <summary>

/// Gets or sets the brightness of the effect.

/// </summary>

public double Brightness

{

get => ((double)(GetValue(BrightnessProperty)));

set => SetValue(BrightnessProperty, value);

}

}

}

5)使用Window.Xaml 代码如下,默认原色:

<wd:Window x:Class="WPFDevelopers.Samples.MainWindow"

xmlns=""

xmlns:x=""

xmlns:d=""

xmlns:mc=""

xmlns:wd="">

<wd:Window.Effect>

<wd:GrayscaleEffect x:Name="grayscaleEffect" Factor="1"/>

</wd:Window.Effect>

<TextBlock Text="开启程序灰度" FontSize="20" Margin="0,20,0,0"/>

<ToggleButton Margin="10" Name="tbGrayscale"

Checked="tbGrayscale_Checked"

Unchecked="tbGrayscale_Unchecked"

HorizontalAlignment="Left"/>

6)使用Window.Xaml.cs 灰度代码如下:

private void tbGrayscale_Checked(object sender, RoutedEventArgs e)

{

Create(0);

}

void Create(double to)

{

var sineEase = new SineEase() { EasingMode = EasingMode.EaseOut };

var doubleAnimation = new DoubleAnimation

{

To = to,

Duration = TimeSpan.FromMilliseconds(1000),

EasingFunction = sineEase

};

grayscaleEffect.BeginAnimation(GrayscaleEffect.FactorProperty, doubleAnimation);

}

private void tbGrayscale_Unchecked(object sender, RoutedEventArgs e)

{

Create(1);

}

参考资料[1]

原文链接:

[2]

简易源码:

[3]

ShaderEffect:

[4]

PixelShader:

[5]

RegisterPixelShaderSamplerProperty:

[6]

DirectX SDK:

[7]

Nuget :

[8]

Shazzam Shader Editor:

标签: #net framework35 sp1