最近大家有没有发现,很多App
的首页变成灰白色了。这种灰白色很多时候用于纪念,哀悼等。那么使用WPF
如何来做到这种效果呢?
要实现的这种效果,我们会发现,它其实不仅仅是要针对图片,而是要针对整个窗口来实现灰白色。
如果只是针对图片的话,我可以可以对图片进行灰阶转换,即可达到灰色效果。
以下是图片转灰阶的代码,当然方法不仅仅是这一种:
//……省略……
FormatConvertedBitmap grayImage = new FormatConvertedBitmap();
grayImage.BeginInit();
grayImage.Source = originImage as BitmapSource;
grayImage.DestinationFormat = PixelFormats.Gray32Float;
grayImage.EndInit();
//……省略……
上述方法也可以直接在xaml
里面表示。
<Image.Source>
<FormatConvertedBitmap DestinationFormat="Gray32">
<FormatConvertedBitmap.Source>
<BitmapImage UriSource="Images\1.png" />
</FormatConvertedBitmap.Source>
</FormatConvertedBitmap>
</Image.Source>
如果我们想针对整个窗口应用这种灰色的效果,那我们可以用着色器特效(ShaderEffect
)来实现。
说明:
*.fx
格式文件:是一种应用特效效果文件,也叫渲染管线的配置文件。编写该文件语言名为高阶着色器语言(High Level Shader Language,简称HLSL),由微软拥有及开发的一种语言。*.ps
格式文件:是通过*.fx
文件编译出来的文件,该文件是通过ShaderEffect
所指定的原始文件。通过ShaderEffect
类,将其应用于WPF
。
灰阶相关 fx
,ps
等文件已有大佬写好了,我们直接拿来用即可跳转下载。相关解释,会在注释中说明。
渲染管线配置文件(*.fx)
//sampler2D 2D纹理采样器
//s0中,s表示取样器,0是表示取样器的子组件编号
sampler2D implicitInput : register(s0);
//c 表示缓冲区偏移量
float factor : register(c0);
//TEXCOORD 表示纹理坐标;COLOR 漫反射/镜面反射颜色
float4 main(float2 uv : TEXCOORD) : COLOR
{
//返回纹理implicitInput在uv位置的颜色。
float4 color = tex2D(implicitInput, uv);
//将颜色转成灰阶
float gray = color.r * 0.3 + color.g * 0.59 + color.b *0.11;
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;
}
应用WPF中特效类
//灰阶特效
public class GrayscaleEffect : ShaderEffect
{
//将像素着色器映射到灰阶着色器
private static PixelShader _pixelShader = new PixelShader() { UriSource = new Uri(@"pack://application:,,,/GrayscaleEffect;component/GrayscaleEffect.ps") };
public GrayscaleEffect()
{
PixelShader = _pixelShader;
//更新着色器的值
UpdateShaderValue(InputProperty);
//该属性可以不要,该熟悉用于彩色到灰色过渡效果
UpdateShaderValue(DesaturationFactorProperty);
}
public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(GrayscaleEffect), 0);
public Brush Input
{
get { return (Brush)GetValue(InputProperty); }
set { SetValue(InputProperty, value); }
}
public static readonly DependencyProperty DesaturationFactorProperty = DependencyProperty.Register("DesaturationFactor", typeof(double), typeof(GrayscaleEffect), new UIPropertyMetadata(0.0, PixelShaderConstantCallback(0), CoerceDesaturationFactor));
//用于调节过渡效果
public double DesaturationFactor
{
get { return (double)GetValue(DesaturationFactorProperty); }
set { SetValue(DesaturationFactorProperty, value); }
}
private static object CoerceDesaturationFactor(DependencyObject d, object value)
{
GrayscaleEffect effect = (GrayscaleEffect)d;
double newFactor = (double)value;
if (newFactor < 0.0 || newFactor > 1.0)
{
return effect.DesaturationFactor;
}
return newFactor;
}
}
在WPF
里面的使用示例:
<!--effect 代表GrayscaleEffect所在的命名空间-->
<Grid.Effect>
<effect:GrayscaleEffect/>
</Grid.Effect>
需要应用到哪个根元素上,就将该特效给对应元素的 Effect
赋值即可。
这种实现方法,性能还是很不错的,如果想对Shader
有更深入的认识,可以阅读《DirectX 3D HLSL 高级实例精讲》
.
欢迎转载分享,如若转载,请标注署名。
博客链接1:https://huchengv5.gitee.io/
博客链接2:https://huchengv5.github.io/
微信公众号:
本文会经常更新,请阅读原文: https://huchengv5.gitee.io//post/WPF-%E5%A6%82%E4%BD%95%E6%98%BE%E7%A4%BA%E7%81%B0%E8%89%B2%E7%89%B9%E6%95%88.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名胡承(包含链接: https://huchengv5.gitee.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。