WPF 图像处理:播放GIF动画、将Bitmap转换为BitmapSource、将MemoryStream转换为BitmapSource
WPF 图像处理
以前一直都是用 WinForm 写窗体,最近准备转向WPF,然而尝试之后,我发现WPF的设计思路与Windows有许多差别,比如最简单的图片控件,就有许多的坑等着你去踩。因为在WPF中,无法直接应用 Bitmap 对象到 Image 控件之中,而 Image 控件一般情况下只能通过读取URI才能加载图片。
通过一番google和摸索后,我总算是总结了一些 Image 控件的应用技巧,做个记录防止忘了,也顺便分享一下。
以下示例中,XAML中拥有一个名为
img
的 Image 控件!<Image Name="img"></Image>
正常加载流程
<Image Name="img" Source="xxx/xxx.jpg"></Image>
Dim image As New BitmapImage
image.BeginInit()
image.UriSource = New Uri("xxx/xxx.jpg") '读取图片路径
image.EndInit()
img.Source = image '为Image标签赋值Source对象,加载并显示图片
将 Bitmap 转换为 BitmapSource
WPF工程默认不会导入Windows窗体类库,因此您需要先自行导入System.Drawing.dll
类库。Shared Function BitmapToBitmapSource(bmp As System.Drawing.Bitmap) As BitmapSource
Dim ret As BitmapSource
Try
ret = Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions)
Catch ex As Exception
ret = Nothing
End Try
Return ret
End Function
将 Bytes 或 MemoryStream 转换为 BitmapSource
Shared Function BytesToBitmapSource(bytes As Byte()) As BitmapSource
Dim ms As New IO.MemoryStream
ms.Write(bytes, 0, bytes.Length)
Return MemoryStreamToBitmapSource(ms)
End Function
Shared Function MemoryStreamToBitmapSource(ms As System.IO.MemoryStream) As BitmapSource
Dim ret As New BitmapImage
ret.BeginInit()
ret.StreamSource = ms '就是这么简单
ret.EndInit()
'ms.Dispose() '不要尝试清除内存流,否则会导致图片失效
Return ret
End Function
加载GIF动画
在 WPF 之中,默认的 Image 控件是无法加载GIF动画的,因此需要你下载一个WpfAnimatedGif
组件!github https://github.com/XamlAnimatedGif/WpfAnimatedGif
nuget https://www.nuget.org/packages/WpfAnimatedGif
安装完组件之后,在需要应用GIF动画的XAML代码中,应用下面的代码:
<Window x:Class="demo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
>
<Grid>
<Image Name="img" gif:ImageBehavior.AnimatedSource=".../xxx.gif" />
</Grid>
</Window>
其中 Window 标签内的属性 xmlns:gif="http://wpfanimatedgif.codeplex.com"
是应用 WpfAnimatedGif 的关键,请一定记得添加上!(也可以使用
xmlns:gif="clr-namespace:WpfAnimatedGif;assembly=WpfAnimatedGif"
来声明)之后,如果你想直接在XAML中加载GIF动画,只需要将原本的
Source
属性修改为 gif:ImageBehavior.AnimatedSource
,用来加载GIF动画!如果你想要用代码完成动画加载,只需要参考下面的示例:
(记得先导入命名空间
Imports WpfAnimatedGif
)Dim image = New BitmapImage()
image.BeginInit()
image.UriSource = New Uri(".../xxx.gif")
image.EndInit()
ImageBehavior.SetAnimatedSource(img, image) '设置动画源,无需调用 img.Source = image
重复次数
设置重复很简单,只需应用gif:ImageBehavior.RepeatBehavior
属性即可。<Image Name="img"
gif:ImageBehavior.RepeatBehavior="3x"
gif:ImageBehavior.AnimatedSource="xxx.gif"
/>
参数 3x
代表重复播放3次;你也可以设置为时间格式
0:0:10
表示只播放10秒钟;参数
Forever
或 0x
表示永远播放。代码控制示例:
' 重复3次
ImageBehavior.SetRepeatBehavior(img, new Animation.RepeatBehavior(3));
' 播放10秒
ImageBehavior.SetRepeatBehavior(img, new Animation.RepeatBehavior(TimeSpan.FromSeconds(10)));
' 无限重播
ImageBehavior.SetRepeatBehavior(img, Animation.RepeatBehavior.Forever);
' 最后别忘记设置一下源
ImageBehavior.SetAnimatedSource(img, image)
动画播放完成通知
<Image gif:ImageBehavior.RepeatBehavior="3x"
gif:ImageBehavior.AnimatedSource="Images/animated.gif"
gif:ImageBehavior.AnimationCompleted="AnimationCompleted"
/>
如果设置为无限重复播放,则不会引发此事件。手动控制动画
在手动控制动画之前,最好先禁止 GIF 自动播放:<Image Name="img"
gif:ImageBehavior.AnimatedSource="animated.gif"
gif:ImageBehavior.AutoStart="False"
/>
手动控制代码示例:' 获取控制权限
Dim controller = ImageBehavior.GetAnimationController(img)
controller.Pause() '暂停
controller.Play() '播放
controller.GotoFrame(controller.FrameCount - 1) '跳到最后一帧
设置动画速度
下方示例为三倍速播放:<Image Name="img" gif:ImageBehavior.AnimationSpeedRatio="3.0" />
ImageBehavior.SetAnimationSpeedRatio(img, 3.0)
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。