WPF中图像处理的方法介绍

和Winform中的GDI+相比,WPF提供了一组新的API用于显示和编辑图像。新API特点如下:

  • 适用于新的或专用图像格式的扩展性模型。
  • 对包括位图 (BMP)、联合图像专家组 (JPEG)、可移植网络图形 (PNG)、标记图像文件格式 (TIFF)、Microsoft Windows Media 照片、图形交换格式 (GIF) 和图标 (.ico) 在内的本机图像格式增强了性能和安全性。
  • 高位深图像数据的保留最多 32 位/通道。
  • 非破坏性图像缩放、裁切和旋转。
  • 简化的颜色管理
  • 支持文件内的专用元数据。
  • 托管组件利用非托管基础结构提供图像与其他 WPF 功能(如用户界面 (UI)、动画和图形)的无缝集成。托管组件还可以从 Windows Presentation Foundation (WPF) 图像处理编解码器扩展性模型获益,利用该模型可以实现自动识别 WPF 中的新图像格式。

大部分托管的 WPF 图像处理 API 驻留在 System.Windows.Media.Imaging 命名空间中,不过,几个重要的类型(如 ImageBrush 和 ImageDrawing)都驻留在 System.Windows.Media 命名空间,Image 驻留在 System.Windows.Controls 命名空间。

下面我通过一个简单的示例演示一下新的API的使用方法:

图像编码格式转换:

var imageStreamSource = File.OpenRead(@"r:\1\24.bmp");
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
var bitmapFrame = decoder.Frames[0];

//在界面上显示图片
//image1.Source = bitmapFrame;

var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(bitmapFrame);
encoder.Save(File.Create(@"r:\1\3.jpg"));

这个功能非常简单,就是把一个bmp格式的图片转换为了一个jpg格式的图片。这个示例也显示了WPF的图像处理的基本方式:

  • 从解码器(xxxDecoder)中获取图像信息
    创建解码器后,图像信息就保存在Frames(虽然大部分图像(jpg,bmp,png等)只有一帧,但GIF,ico等图像有多帧)属性中了。
  • 用编码器(xxxEncoder)保持图像信息
    相应的,编码时只要创建编码器,并设置相应的帧即可。

图像处理:

常用的图像处理包括缩放、裁切和旋转等,如下是一个将图像旋转90度的例子。

var imageStreamSource = File.OpenRead(@"r:\1\24.bmp");
var decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
var bitmapFrame = decoder.Frames[0];  

TransformedBitmap myRotatedBitmapSource = new TransformedBitmap();
myRotatedBitmapSource.BeginInit();
myRotatedBitmapSource.Source = bitmapFrame;  

// 旋转90度
myRotatedBitmapSource.Transform = new RotateTransform(90);
myRotatedBitmapSource.EndInit(); 

//旋转

var rotate = new RotateTransform(90);
var rotatedBitMap = new TransformedBitmap(bitmapFrame, rotate);

image1.Source = rotatedBitMap;

////裁剪
//CroppedBitmap chainedBitMap = new CroppedBitmap(bitmapFrame,new Int32Rect(100, 0, (int)bitmapFrame.Width - 100, (int)bitmapFrame.Height));

////缩放
//var scare = new ScaleTransform(1.5, 2);
//var scaredBitMap = new TransformedBitmap(bitmapFrame, scare);

var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rotatedBitMap));
//encoder.Frames.Add(BitmapFrame.Create(scaredBitMap));
//encoder.Frames.Add(BitmapFrame.Create(chainedBitMap));
encoder.Save(File.Create(@"r:\1\3.jpg"));

和上面的例子相比,这里就是多了一个TransformedBitmap变换,其实这和xaml中的变换时一样的。

<Image Width="150" Margin="5" Grid.Column="0" Grid.Row="1">
  <Image.Source>
    <TransformedBitmap Source="/sampleImages/watermelon.jpg" >
      <TransformedBitmap.Transform>
        <RotateTransform Angle="90"/>
      </TransformedBitmap.Transform>
    </TransformedBitmap>
  </Image.Source>
</Image>

其它变换也都可以参照xaml中处理方式进行,这里就不过多介绍了。

到此这篇关于WPF图像处理的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#自定义WPF中Slider的Autotooltip模板

    Slider控件有一个我比较喜欢的属性"AutoToolTip",可以在拖动的过程中显示当前刻度,然而这个刻度却不支持模板定制,并且就连自定义格式也不行.这就大大的限制了它的使用范围.网上有篇文章解决了这个问题,可以实现自定义显示格式 代码如下: /// <summary> /// A Slider which provides a way to modify the /// auto tooltip text by using a format string. /// &

  • WPF数据绑定中的RelativeSource属性

    一.简介 一个在Binding中比较重要的知识点——RelativeSource. 使用RelativeSource对象指向源对象.用这个可以在当前元素的基础上查找其他对象用于绑定到源对象.在实际使用Binding的过程中大部分时间Binding都放在了数据模板和控件模板中,(数据模板是控件模板用于定义控件的UI). 在模板中编写Binding时有时候无法直接拿到我们需要绑定的数据对象,我们不能确定我们需要的Source对象叫什么,但是我们直到了我们需要使用的对象在UI布局上的相对关系.比如控件

  • WPF实现流光动画特效

    一.代码 <Window.Resources> <!--外--> <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever"> <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Stroke).(LinearGradientBrush.StartPoint)" Storybo

  • WPF数据驱动修改绑定

    一.简介 在XAML文件中我们创建了一个TextBlock 和一个Slider.2个控件.我们把TextBlock的Text属性(用于显示文本的属性)设置为{Binding Intelligence}.把Slider的Value属性(滑块的当前值)设置为{Binding Intelligence}. 二.代码案例 XMAL: <Grid> <StackPanel> <TextBlock Text="{Binding Intelligence}"/>

  • WPF使用VisualTreeHelper进行命中测试

    一.简介 我们有时候又需求从当前视觉树中找一些东西,比如鼠标按下的时候,看看鼠标下的元素都有什么.又比如某块区域下有哪些元素?某个坐标点下有哪些元素?这些需求在使用 命中测试的时候,可以非常方便和快速的去找到我们需要的内容. 二.代码案例 我在一个画板上在不同的位置放了3个圆形.给他们放置了不同的位置和填充不同的颜色,我们通过命中测试判断如果鼠标在圆上抬起了,我们读取当前圆的填充颜色. XAML: <Grid MouseLeftButtonUp="Grid_MouseLeftButtonU

  • WPF实现雷达扫描图的绘制详解

    目录 前言 制作思路 具体实现 前言 实现一个雷达扫描图. 源代码在TK_King/雷达 (gitee.com),自行下载就好了 制作思路 绘制圆形(或者称之轮) 绘制分割线 绘制扫描范围 添加扫描点 具体实现 首先我们使用自定义的控件.你可以使用vs自动添加,也可以手动创建类.注意手动创建时要创建Themes/Generic.xaml的文件路径哦. 控件继承自itemscontrol,取名叫做Radar. 我们第一步思考如何实现圆形或者轮,特别是等距的轮. 我们可以使用简单的itemscont

  • C#对WPF数据绑定的菜单插入分隔Seperator

    WPF代码展示 <Window.Resources> <local:Source x:Key="src"/> </Window.Resources> <StackPanel> <Menu> <MenuItem Header="Animals" ItemsSource="{Binding Source={StaticResource src}}" /> </Menu>

  • C# WPF后台动态添加控件实战教程

    目录 概述 ​项目介绍 代码设计 源码 总结 概述 在Winform中从后台添加控件相对比较容易,但是在WPF中,我们知道界面是通过XAML编写的,如何把后台写好的控件动态添加到前台呢?本节举例介绍这个问题. 这里要用到UniformGrid布局,UniformGrid 是一种横向的网格分割.纵向的网格分割分别是均等的分割的布局类型. ​项目介绍 -. 这里界面添加一个ComboBox用来下拉选择图片数量: -. 添加一个button用来执行图片显示: dispaly下方是图片显示区域 代码设计

  • WPF中图像处理的方法介绍

    和Winform中的GDI+相比,WPF提供了一组新的API用于显示和编辑图像.新API特点如下: 适用于新的或专用图像格式的扩展性模型. 对包括位图 (BMP).联合图像专家组 (JPEG).可移植网络图形 (PNG).标记图像文件格式 (TIFF).Microsoft Windows Media 照片.图形交换格式 (GIF) 和图标 (.ico) 在内的本机图像格式增强了性能和安全性. 高位深图像数据的保留最多 32 位/通道. 非破坏性图像缩放.裁切和旋转. 简化的颜色管理 支持文件内的

  • 基于StringBuilder类中的重要方法(介绍)

    下面的API注解包含了StringBuilder类中的重要方法 append(boolean b):将 boolean 参数的字符串表示形式追加到序列. append(char c):将 char 参数的字符串表示形式追加到此序列. append(char[] str):将 char 数组参数的字符串表示形式追加到此序列. append(char[] str,int offset,int len):将 char 数组参数的子数组的字符串表示形式追加到此序列. append(CharSequenc

  • 重写Java中的equals方法介绍

    Java中,只有8种基本类型不是对象,例如:4种整形类型(byte, short, int,long),2种浮点类型(flout, double),boolean, char不是对象,其他的所有类型,不论是对象数组,列表等都扩展了Object类.了解学习Object中方法的设计原理和实现方式有助于更好的学习理解java语言.下面,我们首先学习一下Object中的equals方法. 判断两个对象相等时,JVM首先查找两个对象的hashCode, 如果两者hashCode不同,则返回false;如果

  • Java中的hashcode方法介绍

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个方法的声明可知,该方法返回一个int类型的数值,并且是本地方法,因此在Object类中并没有给出具体的实现. 为何Object类需要这样一个方法?它有什么作用呢?今天我们就来具体探讨一下hashCode方法. 一.hashCode方法的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到has

  • java ArrayList中的remove方法介绍

    先看一段代码,看看自定义的ArrayList中的remove设计是否有问题. public class MyArrayList { private Object[] mData = new Object[0]; private int mSize = 0; // 删除第i个元素 public void remove(int i) { if (i < 0 || i >= mSize) return; for (int index = i; index < mSize - 1; index+

  • Java中PrintWriter使用方法介绍

    目录 简介 文本文件的转码复制 运行程序 简介 PrintWriter 与 PrintStream 相同.PrintStream 只能接字节流,而 PrintWriter 既能接字节流又能接字符流. PrintStream 最终输出的总是 byte 数据,而 PrintWriter 则是扩展了 Writer 接口,它的 print()/println() 方法最终输出的是 char 数据.两者的使用方法几乎是一模一样的. 文本文件的转码复制 public class Main { public

  • Javascript中的call()方法介绍

    在Mozilla的官网中对于call()的介绍是: 复制代码 代码如下: call() 方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法. Call() 语法 复制代码 代码如下: fun.call(thisArg[, arg1[, arg2[, ...]]]) Call() 参数 thisArg 复制代码 代码如下: 在fun函数运行时指定的this值.需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为nul

  • go语言中函数与方法介绍

    在C#或者Java里面我们都知道,一个Class是要包含成员变量和方法的,对于GO语言的Struct也一样,我们也可以给Struct定义一系列方法. 一.怎么定义一个方法? Go的方法是在函数前面加上一个接收者,这样编译器就知道这个方法属于哪个类型了.例如: package demo1 import ( "fmt" ) type Student struct { Name string Age int Class string } func (stu Student) GetUserI

  • Python TestCase中的断言方法介绍

    前言 测试是一个贯穿于整个开发过程的连续过程,从某个意义上说,软件开发的过程实际上就是测试过程.正如Martin Fowler所说的"在你不知道如何测试代码之前,就不该编写程序.而一旦你完成了程序,测试代码也应该完成.除非测试成功,你不能认为你编写出了可以工作的程序." Python TestCase断言方法 unittest.TestCase 类中提供了很多断言方法, 通过这些断言方法,我们就可以检查程序逻辑是否符合预期. 方法 说明 assertEqual(x,y) 验证 x =

  • Lua中执行系统命令方法介绍

    Lua中,os.execute可以执行dos命令,但是返回的是系统状态码,默认输出. io.popen()也可以执行dos命令,但是返回一个文件.eg: 复制代码 代码如下: local t = io.popen('svn help') local a = t:read("*all") --a返回一个字符串,内容是svn help的内容 如果想执行某命令或程序可选os.execute(),如果还想捕捉该执行结果可用io.popen() eg:复制文件 复制代码 代码如下: os.exe

随机推荐