一.前言
申明: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控件的主要解决的问题:
为了能扩展支持多种类型的缩略图,设计了一个简单的模式,用VS自带的工具生成的代码视图:
3.1 多种类型的缩略图扩展
首先定义一个图片类型枚举:
然后定义了一个接口,生成图片数据源ImageSource
如上面的代码视图,有三个实现,视频缩略图VedioThumbnailProvider没有实现完成,基本方法是利用一个第三方工具ffmpeg来获取第一帧图像然后创建ImageSource。
ImageThumbnailProvider:普通图片缩略图实现(调用的2.2方法):
WebImageThumbnailProvider:网络图片缩略图实现(下载图片数据后调用2.1方法):
简单工厂ThumbnailProviderFactory实现:
3.2 缩略图控件ThumbnailImage
先看看效果图吧,下面三张图片,图1是本地图片,图2是网络图片,图3也是网络图片,为什么没显示呢,这张图片用的是国外的图片链接地址,异步加载(加载比较慢,还没出来的!)
ThumbnailImage实际是继承在微软的图片控件Image,因此没有样式代码,继承之后,主要的目的就是重写Imagesource的处理过程,详细代码:
View Code
其中异步用的线程池执行图片加载, Executer.TryRunByThreadPool是一个辅助方法,用于在线程池中执行一个委托方法。缓存的实现用的是另外一个轻量级内存缓存组建(使用微软HttpRuntime.Cache的缓存机制),关于缓存的方案网上很多,这里就不介绍了。
示例代码:
四.动态图片gif播放控件
实现代码:
五.图片列表样式,支持大数据量的虚拟化
先看看效果图(gif图,有点大):
用的是ListView作为列表容器,因为Listview支持灵活的扩展,为了实现上面的效果,集合容器ItemsPanel只能使用WrapPanel,样式本身并不复杂:
主要难道在于 WrapPanel是不支持虚拟化的,网上找了一个开源的WrapPanel虚拟化实现=VirtualizingWrapPanel,它有点小bug(滑动条长度计算有时候不是很准确),不过完全不影响使用,代码:
附录:参考引用
<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 & RichTextBox & 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>
个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。