当前位置:文档之家› WPF自定义控件与样式(12)

WPF自定义控件与样式(12)

WPF自定义控件与样式(12)WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表时间2015-12-01 09:21:00博客园-原创精华区原文/anding/p/5009120.html主题WPFBitmap一.前言申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。

本文主要针对WPF项目开发中图片的各种使用问题,经过总结,把一些经验分享一下。

内容包括:WPF常用图像数据源ImageSource的创建;自定义缩略图控件ThumbnailImage,支持网络图片、大图片、图片异步加载等特性;动态图片gif播放控件;图片列表样式,支持大数据量的虚拟化;二.WPF常用图像数据源ImageSource的创建<Image Source="../Images/qq.png"></Image>这是一个普通Image控件的使用,Source的数据类型是ImageSource,在XAML中可以使用文件绝对路径或相对路径,ImageSource是一个抽象类,我们一般使用BitmapSource、BitmapImage等。

但在实际项目中,有各种各样的需求,比如:从Bitmap创建ImageSource对象;从数据流byte[]创建ImageSource对象;从System.Drawing.Image创建ImageSource对象;从一个大图片文件创建一个指定大小的ImageSource对象;2.1 从System.Drawing.Image创建指定大小ImageSource 对象/// <summary>/// 使用System.Drawing.Image创建WPF使用的ImageSource类型缩略图(不放大小图)/// </summary>/// <paramname="sourceImage">System.Drawing.Image 对象</param>/// <param name="width">指定宽度</param> /// <param name="height">指定高度</param> public static ImageSource CreateImageSourceThumbnia(System.Drawing.Image sourceImage, double width, double height){if (sourceImage == null) return null;double rw = width / sourceImage.Width;double rh = height / sourceImage.Height;var aspect = (float)Math.Min(rw, rh);int w = sourceImage.Width, h = sourceImage.Height;if (aspect < 1){w = (int)Math.Round(sourceImage.Width * aspect); h = (int)Math.Round(sourceImage.Height * aspect);}Bitmap sourceBmp = new Bitmap(sourceImage, w, h); IntPtr hBitmap = sourceBmp.GetHbitmap(); BitmapSource bitmapSource =Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions()); bitmapSource.Freeze();System.Utility.Win32.Win32.DeleteObject(hBitmap); sourceImage.Dispose();sourceBmp.Dispose();return bitmapSource;}2.2 从一个大图片文件创建一个指定大小的ImageSource对象/// <summary>/// 创建WPF使用的ImageSource类型缩略图(不放大小图)/// </summary>/// <param name="fileName">本地图片路径</param>/// <param name="width">指定宽度</param>/// <param name="height">指定高度</param> public static ImageSource CreateImageSourceThumbnia(string fileName, double width, double height){System.Drawing.Image sourceImage =System.Drawing.Image.FromFile(fileName);double rw = width / sourceImage.Width;double rh = height / sourceImage.Height;var aspect = (float)Math.Min(rw, rh);int w = sourceImage.Width, h = sourceImage.Height;if (aspect < 1){w = (int)Math.Round(sourceImage.Width * aspect); h = (int)Math.Round(sourceImage.Height * aspect);}Bitmap sourceBmp = new Bitmap(sourceImage, w, h); IntPtr hBitmap = sourceBmp.GetHbitmap(); BitmapSource bitmapSource =Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions()); bitmapSource.Freeze();System.Utility.Win32.Win32.DeleteObject(hBitmap); sourceImage.Dispose();sourceBmp.Dispose();return bitmapSource;}2.3 从Bitmap创建指定大小的ImageSource对象/// <summary>/// 从一个Bitmap创建ImageSource/// </summary>/// <param name="image">Bitmap对象</param>/// <returns></returns>public static ImageSource CreateImageSourceFromImage(Bitmap image){if (image == null) return null;try{IntPtr ptr = image.GetHbitmap();BitmapSource bs =Imaging.CreateBitmapSourceFromHBitmap(ptr, IntPtr.Zero, Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions());bs.Freeze();image.Dispose();System.Utility.Win32.Win32.DeleteObject(ptr);return bs;}catch (Exception){return null;}}2.4 从数据流byte[]创建指定大小的ImageSource对象/// <summary>/// 从数据流创建缩略图/// </summary>public static ImageSource CreateImageSourceThumbnia(byte[] data, double width, double height){using (Stream stream = new MemoryStream(data, true)) {using (Image img = Image.FromStream(stream)){return CreateImageSourceThumbnia(img, width, height);}}}三.自定义缩略图控件ThumbnailImage ThumbnailImage控件的主要解决的问题:为了能扩展支持多种类型的缩略图,设计了一个简单的模式,用VS自带的工具生成的代码视图:3.1 多种类型的缩略图扩展首先定义一个图片类型枚举:/// <summary>/// 缩略图数据源源类型/// </summary>public enum EnumThumbnail{Image,Vedio,WebImage,Auto,FileX,}然后定义了一个接口,生成图片数据源ImageSource/// <summary>/// 缩略图创建服务接口/// </summary>public interface IThumbnailProvider{/// <summary>/// 创建缩略图。

相关主题