翼度科技»论坛 编程开发 .net 查看内容

WPF/C#实现图像滤镜优化方案:打造炫目视觉体验!

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
原因:我之所以想做这个项目,是因为在之前查找关于C#/WPF相关资料时,我发现讲解图像滤镜的资源非常稀缺。此外,我注意到许多现有的开源库主要基于CPU进行图像渲染。这种方式在处理大量图像时,会导致CPU的渲染负担过重。因此,我将在下文中介绍如何通过GPU渲染来有效实现图像的各种滤镜效果。
生成的效果


生成效果的方法:我主要是通过参考Shazzam Shader Editor来编写HLSL像素着色器。

HLSL(High Level Shader Language,高级着色器语言)是Direct3D着色器模型所需的一种语言。WPF不仅支持Direct3D 9,还支持使用HLSL来创建着色器。虽然可以使用多种编辑器来编写HLSL,但Shazzam Shader Editor是一款专为WPF设计的编辑器,它专门用于实现像素着色器。使用Shazzam可以简化将像素着色器集成到WPF项目中所需的各种手动操作。(关于如何使用Shazzam,可在线查找详细教程。)
在我的项目中,我根据所需的效果生成相应的.PS和.CS文件,并将这些文件添加到类库中。接着,我会在具体的项目中引入这个库来实现效果

项目实现细节

开发环境


  • 使用的MVVM库:CommunityToolkit.Mvvm
  • 目标框架:.NET 8.0
  • 开发工具:Visual Studio 2022
使用的样式库

项目中采用了AduSkin样式库。个人建议:​我不特别推荐使用AduSkin,主要是因为它缺乏官方文档,需要通过查看源代码来学习使用。此外,一些样式的命名与源代码中的不一致,这可能会导致一些困惑。(备注:我最初选择使用AduSkin是因为其UI设计在网络上获得了好评,尽管某些效果确实很吸引人,但缺少文档导致使用上的不便。)

项目结构概述

项目在构建过程中,考虑到几种特效之间存在一些共同的重复元素,如图片展示和图片导入功能,因此我将这些共用功能模块化。

  • 操作区域的定制化:​对于每种不同的特效,操作区的需求也不尽相同。在Common控件中,我使用了Option控件来进行替代,以便于在外部进行定制。
  • 特效的动态调整:​每种特效的具体实现都有所不同,因此我设定了一个独立的属性ImageEffect,允许从外部动态修改。
  • 公共控件:CommonEffectControl作为一个公共控件,用于整合图片显示和图片导入的共通功能。
具体引用的步骤

需要添加命令空间

  •  xmlns:common="clr-namespace:CT.WPF.MagicEffects.Demo.UserControls.Common"
前台代码
查看代码
  1. <common:CommonEffectControl ImageEffect="{Binding SelectedOrdinary.ObjectShaderEffect}">
  2.      <common:CommonEffectControl.Option>
  3.          <StackPanel Orientation="Vertical">
  4.              <Border BorderBrush="Transparent" BorderThickness="0">
  5.                  <Skin:MetroScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible">
  6.                      <ListView
  7.                          Width="240"
  8.                          Height="550"
  9.                          BorderThickness="0"
  10.                          ItemsSource="{Binding Ordinarys}"
  11.                          ScrollViewer.HorizontalScrollBarVisibility="Disabled"
  12.                          ScrollViewer.VerticalScrollBarVisibility="Hidden"
  13.                          SelectedItem="{Binding SelectedOrdinary, Mode=TwoWay}"
  14.                          SelectionMode="Single">
  15.                          <ListView.ItemTemplate>
  16.                              <DataTemplate>
  17.                                  <StackPanel
  18.                                      MinHeight="110"
  19.                                      VerticalAlignment="Center"
  20.                                      Orientation="Vertical">
  21.                                      <Viewbox
  22.                                          Width="99"
  23.                                          Height="78"
  24.                                          Margin="2">
  25.                                          <Image Effect="{Binding ObjectShaderEffect}" Source="{Binding Path=Main.SelectedImagePath, Source={StaticResource Locator}}" />
  26.                                      </Viewbox>
  27.                                      <TextBlock
  28.                                          HorizontalAlignment="Center"
  29.                                          FontSize="14"
  30.                                          Foreground="{Binding RelativeSource={RelativeSource AncestorType={x:Type Skin:MetroWindow}}, Path=BorderBrush, Mode=TwoWay}"
  31.                                          Text="{Binding Title}"
  32.                                          TextWrapping="Wrap" />
  33.                                  </StackPanel>
  34.                              </DataTemplate>
  35.                          </ListView.ItemTemplate>
  36.                          <ListView.ItemsPanel>
  37.                              <ItemsPanelTemplate>
  38.                                  <WrapPanel Orientation="Horizontal" />
  39.                              </ItemsPanelTemplate>
  40.                          </ListView.ItemsPanel>
  41.                      </ListView>
  42.                  </Skin:MetroScrollViewer>
  43.              </Border>
  44.          </StackPanel>
  45.      </common:CommonEffectControl.Option>
  46. </common:CommonEffectControl>
复制代码
ViewModel部分
查看代码
  1.    partial class OrdinaryEffectViewModel : ObservableObject {
  2.       public OrdinaryEffectViewModel() {
  3.           Ordinarys = new ObservableCollection<Ordinarys> {
  4.               new Ordinarys(){ Title="灰度", ObjectShaderEffect= new GrayScaleEffect ()},
  5.               new Ordinarys(){ Title="位移", ObjectShaderEffect= new DirectionalBlurEffect ()},
  6.               new Ordinarys(){ Title="老电影", ObjectShaderEffect= new OldMovieEffect ()},
  7.               new Ordinarys(){ Title="锐化", ObjectShaderEffect= new SharpenEffect ()},
  8.           };
  9.       }
  10.       [ObservableProperty]
  11.       private ObservableCollection<Ordinarys> ordinarys;
  12.       [ObservableProperty]
  13.       private Ordinarys selectedOrdinary;
  14.   }
复制代码
model部分
查看代码
  1.   partial class Ordinarys : ObservableObject {
  2.      [ObservableProperty]
  3.      private string? title;
  4.      [ObservableProperty]
  5.      private ShaderEffect? objectShaderEffect;
  6. }
复制代码
还有摄像头滤镜覆盖的效果欢迎大家体验!!!

已经发布nuget:dotnet add package MagicEffects --version 1.0.0
github:CT.WPF.MagicEffects
 

来源:https://www.cnblogs.com/qingxi11/p/18138196
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具