首页 > 编程语言 >WPF/C#实现图像滤镜优化方案:打造炫目视觉体验!

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

时间:2024-04-16 15:59:29浏览次数:48  
标签:控件 C# Ordinarys 滤镜 new WPF 着色器

原因:我之所以想做这个项目,是因为在之前查找关于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"

前台代码

查看代码
 <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>

ViewModel部分

查看代码
   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 ()},
          };
      }
      [ObservableProperty]
      private ObservableCollection<Ordinarys> ordinarys;
      [ObservableProperty]
      private Ordinarys selectedOrdinary;
  }

model部分

查看代码
  partial class Ordinarys : ObservableObject {
     [ObservableProperty]
     private string? title;
     [ObservableProperty]
     private ShaderEffect? objectShaderEffect;
 }

还有摄像头滤镜覆盖的效果欢迎大家体验!!!

已经发布nuget:dotnet add package MagicEffects --version 1.0.0

github:CT.WPF.MagicEffects

 

标签:控件,C#,Ordinarys,滤镜,new,WPF,着色器
From: https://www.cnblogs.com/qingxi11/p/18138196

相关文章

  • 具有低功耗、小尺寸和高可靠性,LIFCL-40-9MG121I、LIFCL-40-8MG121I、LIFCL-40-7MG121I
    说明CrossLink-NXFPGA是首款采用Nexus技术平台设计的产品系列,为网络边缘开发工程师提供实现创新的嵌入式视觉解决方案所需的更低功耗、小尺寸和高可靠性。该系列采用低功耗28nmFD-SOI技术,具有小尺寸、高可靠性和出色的性能。该器件适合用于各种应用,包括嵌入式视觉。应用包......
  • 如何在Semantic Kernel中使用第三方代理OpenAI API接口
    最近手里没有官方的OpenAIAPIKey了,只能在第三方代理平台去购买APIKey。但是使用SemanticKernel的时候发现AddOpenAIChatCompletion不像AddAzureOpenAIChatCompletion那样可以选择终结点去看了下SemanticKernel项目下的issues,这个问题被提及了好几次,但是官方仍然没有提供End......
  • vue3中使用scss
    安装依赖npminstallsasssass-loader--save-dev局部使用<stylescopedlang="scss">...定义样式</style> 全局共享样式变量,在assets/style文件夹中定义mixin.scss文件,并设置一些样式;在其他文件使用定义的变量前需要引入样式文件表  在vite.config.ts文件中......
  • CentOS 7配置Nginx反向代理的步骤
    安装Nginx:如果你的服务器还没有安装Nginx,你可以使用以下命令来安装:sudoyuminstallepel-releasesudoyuminstallnginx创建或修改Nginx配置文件:默认的Nginx配置文件通常位于/etc/nginx/conf.d/目录下。你可以在这个目录下创建一个新的配置文件,例如yourdomain.conf:sudo......
  • nova rescue原理笔记
    说明:场景示例,虚机的启动盘的一个文件被误删除了导致无法再次启动了,或者admin的密码忘记了。Rescue功能提供一个解决这类问题的手段。备注:不能rescue一个volume-backedinstance前提默认情况下,实例从提供的救援映像或新的映像启动原始实例映像的副本(如果未提供救援映像)。......
  • 十三载求索续风华,数智化扬帆启新航 | 万字长文回顾DTC 2024
    4月13日下午,为期两天的第十三届数据技术嘉年华(DTC2024)在北京新云南皇冠假日酒店圆满落下帷幕。本次大会由中国数据库联盟与墨天轮社区联合主办,以“智能·云原生·一体化——DB与AI协同创新,模型与架构融合发展”为主题,汇聚80余位行业杰出技术领袖、学术精英、行业实践者、生态布......
  • 禁止chrome自动更新
    1、打开注册表,可以修改win+R,然后输入regedit2、打开HKEY_LOCAL_MACHINE总文件夹下的SOFTWARE子文件夹找到Policies文件3、在该文件夹下进行新增文件,文件夹为新增项,先进行新增Google然后再到该文件夹下新增Update文件夹 4、然后再新增DWORD(32位)值(D),名称修改为UpdateDefau......
  • Effective Python:第2条 遵循PEP 8风格指南
    PEP8文档:https://peps.python.org/pep-0008/与空白有关的建议:用空格(space)表示缩进,而不要用制表符(tab)。和语法相关的每一层缩进都用4个空格表示。每行不超过79个字符。对于占据多行的长表达式来说,除了首行之外的其余各行都应该在通常的缩进级别之上再加4个空格。......
  • 西门子PLC数据类型1-位、位序列、整数、浮点数、日期时间
     本文摘于西门子官网内容一、位、位序列、整数、浮点数、日期时间基本数据类型:包括位、位序列、整数、浮点数、日期时间。此外字符也属于基本数据类型,请参见文档 String 与 WString。此外BCD码虽然不属于数据类型,但也是一种数字表示方式。1.1位和位序列注意:虽然位......
  • vscode 代码格式化设置
    1.设置默认格式化工具ctrl+shift+P,筛选“FormatDocument”,设置Prettier为默认、 2.设置保存自动格式化打开VSCode,并打开你想要格式化的代码文件。在菜单栏中,选择“文件”>“首选项”>“设置”(快捷键Ctrl+,)。在搜索框中输入“formatonsave”,然后点击“编辑insett......