WPF/C#实现图像滤镜优化方案:打造炫目视觉体验!
<p>原因:我之所以想做这个项目,是因为在之前查找关于C#/WPF相关资料时,我发现讲解图像滤镜的资源非常稀缺。此外,我注意到许多现有的开源库主要基于CPU进行图像渲染。这种方式在处理大量图像时,会导致CPU的渲染负担过重。因此,我将在下文中介绍如何通过GPU渲染来有效实现图像的各种滤镜效果。</p><h1>生成的效果</h1>
<p><img src="https://img2024.cnblogs.com/blog/2566188/202404/2566188-20240416151913478-739499952.png"><img src="https://img2024.cnblogs.com/blog/2566188/202404/2566188-20240416151951823-561434197.png"><img src="https://img2024.cnblogs.com/blog/2566188/202404/2566188-20240416152106717-341666130.png"></p>
<h1 style="text-align: left">生成效果的方法:我主要是通过参考Shazzam Shader Editor来编写HLSL像素着色器。</h1>
<p>HLSL(High Level Shader Language,高级着色器语言)是Direct3D着色器模型所需的一种语言。WPF不仅支持Direct3D 9,还支持使用HLSL来创建着色器。虽然可以使用多种编辑器来编写HLSL,但Shazzam Shader Editor是一款专为WPF设计的编辑器,它专门用于实现像素着色器。使用Shazzam可以简化将像素着色器集成到WPF项目中所需的各种手动操作。(关于如何使用Shazzam,可在线查找详细教程。)</p>
<p>在我的项目中,我根据所需的效果生成相应的.PS和.CS文件,并将这些文件添加到类库中。接着,我会在具体的项目中引入这个库来实现效果</p>
<p><img src="https://img2024.cnblogs.com/blog/2566188/202404/2566188-20240416145454164-1680900187.png"></p>
<h1>项目实现细节</h1>
<h3><strong>开发环境</strong></h3>
<ul>
<li>使用的MVVM库:CommunityToolkit.Mvvm</li>
<li>目标框架:.NET 8.0</li>
<li>开发工具:Visual Studio 2022</li>
</ul>
<h3>使用的样式库</h3>
<p>项目中采用了AduSkin样式库。<strong>个人建议:</strong>我不特别推荐使用AduSkin,主要是因为它缺乏官方文档,需要通过查看源代码来学习使用。此外,一些样式的命名与源代码中的不一致,这可能会导致一些困惑。(备注:我最初选择使用AduSkin是因为其UI设计在网络上获得了好评,尽管某些效果确实很吸引人,但缺少文档导致使用上的不便。)</p>
<p><img src="https://img2024.cnblogs.com/blog/2566188/202404/2566188-20240416150522681-1986071508.png"></p>
<h1>项目结构概述</h1>
<p>项目在构建过程中,考虑到几种特效之间存在一些共同的重复元素,如图片展示和图片导入功能,因此我将这些共用功能模块化。</p>
<ul>
<li><strong>操作区域的定制化:</strong>对于每种不同的特效,操作区的需求也不尽相同。在Common控件中,我使用了Option控件来进行替代,以便于在外部进行定制。</li>
<li><strong>特效的动态调整:</strong>每种特效的具体实现都有所不同,因此我设定了一个独立的属性<code>ImageEffect</code>,允许从外部动态修改。</li>
<li><strong>公共控件:</strong><code>CommonEffectControl</code>作为一个公共控件,用于整合图片显示和图片导入的共通功能。</li>
</ul>
<h2>具体引用的步骤</h2>
<p>需要添加命令空间</p>
<ul>
<li><code> xmlns:common="clr-namespace:CT.WPF.MagicEffects.Demo.UserControls.Common"</code></li>
</ul>
<p>前台代码</p>
查看代码
<pre class="highlighter-prismjs language-xml prismjs-lines-highlighted"><code> <common:CommonEffectControl ImageEffect="{Binding SelectedOrdinary.ObjectShaderEffect}">
<common:CommonEffectControl.Option>
<StackPanel Orientation="Vertical">
<Border BorderBrush="Transparent" BorderThickness="0">
<Skin:MetroScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListView
Width="240"
Height="550"
BorderThickness="0"
ItemsSource="{Binding Ordinarys}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
SelectedItem="{Binding SelectedOrdinary, Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
MinHeight="110"
VerticalAlignment="Center"
Orientation="Vertical">
<Viewbox
Width="99"
Height="78"
Margin="2">
<Image Effect="{Binding ObjectShaderEffect}" Source="{Binding Path=Main.SelectedImagePath, Source={StaticResource Locator}}" />
</Viewbox>
<TextBlock
HorizontalAlignment="Center"
FontSize="14"
Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type Skin:MetroWindow}}, Path=BorderBrush, Mode=TwoWay}"
Text="{Binding Title}"
TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Skin:MetroScrollViewer>
</Border>
</StackPanel>
</common:CommonEffectControl.Option>
</common:CommonEffectControl></code></pre>
<p>ViewModel部分</p>
查看代码
<pre class="highlighter-prismjs language-csharp prismjs-lines-highlighted"><code> partial class OrdinaryEffectViewModel : ObservableObject {
public OrdinaryEffectViewModel() {
Ordinarys = new ObservableCollection<Ordinarys> {
new Ordinarys(){ Title="灰度", ObjectShaderEffect= new GrayScaleEffect ()},
new Ordinarys(){ Title="位移", ObjectShaderEffect= new DirectionalBlurEffect ()},
new Ordinarys(){ Title="老电影", ObjectShaderEffect= new OldMovieEffect ()},
new Ordinarys(){ Title="锐化", ObjectShaderEffect= new SharpenEffect ()},
};
}
private ObservableCollection<Ordinarys> ordinarys;
private Ordinarys selectedOrdinary;
}</code></pre>
<p>model部分</p>
查看代码
<pre class="highlighter-prismjs language-csharp prismjs-lines-highlighted"><code> partial class Ordinarys : ObservableObject {
private string? title;
private ShaderEffect? objectShaderEffect;
}</code></pre>
<h4>还有摄像头滤镜覆盖的效果欢迎大家体验!!!</h4>
<p>已经发布nuget:<code>dotnet add package MagicEffects --version 1.0.0</code></p>
<p>github:CT.WPF.MagicEffects</p>
<p> </p>
<span id="cnki_grabber" style="visibility: hidden" data-id="1713253786000"></span><br><br>
来源:https://www.cnblogs.com/qingxi11/p/18138196
頁:
[1]