天天看点

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

一.前言

  申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。

  本文主要针对WPF项目开发中图片的各种使用问题,经过总结,把一些经验分享一下。内容包括: WPF常用图像数据源ImageSource的创建; 自定义缩略图控件ThumbnailImage,支持网络图片、大图片、图片异步加载等特性; 动态图片gif播放控件; 图片列表样式,支持大数据量的虚拟化;

二. WPF常用图像数据源ImageSource的创建

  这是一个普通Image控件的使用,Source的数据类型是ImageSource,在XAML中可以使用文件绝对路径或相对路径,ImageSource是一个抽象类,我们一般使用BitmapSource、BitmapImage等。

  但在实际项目中,有各种各样的需求,比如:

从Bitmap创建ImageSource对象;

从数据流byte[]创建ImageSource对象;

从System.Drawing.Image创建ImageSource对象;

从一个大图片文件创建一个指定大小的ImageSource对象;

2.1 从System.Drawing.Image创建指定大小ImageSource对象  

2.2 从一个大图片文件创建一个指定大小的ImageSource对象  

2.3 从Bitmap创建指定大小的ImageSource对象  

2.4 从数据流byte[]创建指定大小的ImageSource对象  

三.自定义缩略图控件ThumbnailImage

  ThumbnailImage控件的主要解决的问题:

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

  为了能扩展支持多种类型的缩略图,设计了一个简单的模式,用VS自带的工具生成的代码视图:

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

3.1 多种类型的缩略图扩展

  首先定义一个图片类型枚举:  

  然后定义了一个接口,生成图片数据源ImageSource  

  如上面的代码视图,有三个实现,视频缩略图VedioThumbnailProvider没有实现完成,基本方法是利用一个第三方工具ffmpeg来获取第一帧图像然后创建ImageSource。

  ImageThumbnailProvider:普通图片缩略图实现(调用的2.2方法):

  WebImageThumbnailProvider:网络图片缩略图实现(下载图片数据后调用2.1方法):  

  简单工厂ThumbnailProviderFactory实现:  

3.2 缩略图控件ThumbnailImage

  先看看效果图吧,下面三张图片,图1是本地图片,图2是网络图片,图3也是网络图片,为什么没显示呢,这张图片用的是国外的图片链接地址,异步加载(加载比较慢,还没出来的!)

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

  ThumbnailImage实际是继承在微软的图片控件Image,因此没有样式代码,继承之后,主要的目的就是重写Imagesource的处理过程,详细代码:

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

View Code

  其中异步用的线程池执行图片加载, Executer.TryRunByThreadPool是一个辅助方法,用于在线程池中执行一个委托方法。缓存的实现用的是另外一个轻量级内存缓存组建(使用微软HttpRuntime.Cache的缓存机制),关于缓存的方案网上很多,这里就不介绍了。

  示例代码:  

四.动态图片gif播放控件

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

实现代码:  

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

五.图片列表样式,支持大数据量的虚拟化

  先看看效果图(gif图,有点大):

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

  用的是ListView作为列表容器,因为Listview支持灵活的扩展,为了实现上面的效果,集合容器ItemsPanel只能使用WrapPanel,样式本身并不复杂:  

  主要难道在于 WrapPanel是不支持虚拟化的,网上找了一个开源的WrapPanel虚拟化实现=VirtualizingWrapPanel,它有点小bug(滑动条长度计算有时候不是很准确),不过完全不影响使用,代码:  

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表
WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

附录:参考引用  

<a href="http://www.cnblogs.com/anding/p/4961215.html" target="_blank">WPF自定义控件与样式(1)-矢量字体图标(iconfont)</a>

<a href="http://www.cnblogs.com/anding/p/4968050.html" target="_blank">WPF自定义控件与样式(2)-自定义按钮FButton</a>

<a href="http://www.cnblogs.com/anding/p/4970845.html" target="_blank">WPF自定义控件与样式(3)-TextBox &amp; RichTextBox &amp; PasswordBox样式、水印、Label标签、功能扩展</a>

<a href="http://www.cnblogs.com/anding/p/4976559.html" target="_blank">WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式</a>

<a href="http://www.cnblogs.com/anding/p/4979764.html">WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展</a>

<a href="http://www.cnblogs.com/anding/p/4987426.html">WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式</a>

<a href="http://www.cnblogs.com/anding/p/4990492.html">WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式</a>

<a href="http://www.cnblogs.com/anding/p/4993655.html" target="_blank">WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox</a>

<a href="http://www.cnblogs.com/anding/p/4996614.html" target="_blank">WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu</a>

<a href="http://www.cnblogs.com/anding/p/5006279.html">WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现</a>

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

继续阅读