WPF控件到图片的转换
在实际的项目开发中,经常需要将信息保存成图片的形式,如屏幕截图、地图快照等操作,我中最近一个项目中便有这样的需求,项目(WPF)中用到GMap.NET控件,中地图上展示一些信息,过程中可能用户需要将地图信息保存下来,也就是地图快照,我的界面如下所示:
网上查了GMap相关的资料,没有找到GMap怎么截图的方法,最后找到网友提供的方法:将WPF控件转换成图片。
具体实现如下:
namespace QACDR2.Common { internal enum ImageType { Bmp, Gif, Jpeg, Png, Tiff, Wdp } /// <summary> /// 控件到图片的转换 /// </summary> static class ControlToImageConverter { #region 私有方法 /// <summary> /// Convert any control to a PngBitmapEncoder /// </summary> /// <param name="controlToConvert">The control to convert to an ImageSource</param> /// <param name="imageType">The image type will indicate the type of return bitmap encoder</param> /// <returns>The returned ImageSource of the controlToConvert</returns> private static BitmapEncoder GetImageFromControl(FrameworkElement controlToConvert, ImageType imageType) { var bounds = controlToConvert.GetBounds(controlToConvert.Parent as Visual); var renderBitmap = new RenderTargetBitmap((Int32)bounds.Width, (Int32)bounds.Height, 96d, 96d, PixelFormats.Pbgra32); renderBitmap.Render(controlToConvert); BitmapEncoder encoder = GetBitmapEncoderByImageType(imageType); // puch rendered bitmap into it encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); return encoder; } private static Rect GetBounds(this FrameworkElement element, Visual from) { Rect rect = Rect.Empty; try { GeneralTransform transform = element.TransformToVisual(from); rect = transform.TransformBounds(new Rect(0, 0, element.ActualWidth, element.ActualHeight)); // ReSharper disable EmptyGeneralCatchClause } catch // ReSharper restore EmptyGeneralCatchClause { } return rect; } /// <summary> /// Get an encoder by a specify image type /// </summary> /// <param name="type">the image type</param> /// <returns>return an eccoder</returns> private static BitmapEncoder GetBitmapEncoderByImageType(ImageType type) { switch (type) { case ImageType.Bmp: return new BmpBitmapEncoder(); case ImageType.Gif: return new GifBitmapEncoder(); case ImageType.Jpeg: return new JpegBitmapEncoder(); case ImageType.Png: return new PngBitmapEncoder(); case ImageType.Tiff: return new TiffBitmapEncoder(); case ImageType.Wdp: return new WmpBitmapEncoder(); default: return new PngBitmapEncoder(); } } /// <summary> /// Get the iamge type by image file name /// </summary> /// <param name="fileName">the file name of an image</param> /// <returns>the iamge type</returns> private static ImageType GetImageTypeByFileName(string fileName) { ImageType returnType = ImageType.Png; var extension = Path.GetExtension(fileName); if (!String.IsNullOrEmpty(extension)) { switch (extension.ToLower()) { case ".bmp": returnType = ImageType.Bmp; break; case ".gif": returnType = ImageType.Gif; break; case ".jpeg": case ".jpg": case ".jpe": case "jfif": returnType = ImageType.Jpeg; break; case ".png": returnType = ImageType.Png; break; case ".tiff": case ".tif": returnType = ImageType.Tiff; break; case ".wdp": returnType = ImageType.Wdp; break; default: returnType = ImageType.Png; break; } } return returnType; } #endregion #region 提供的方法 /// <summary> /// Get an ImageSource of a control /// </summary> /// <param name="controlToConvert">The control to convert to an ImageSource</param> /// <param name="imageType">the image type</param> /// <returns>The returned ImageSource of the controlToConvert</returns> public static BitmapSource GetImageOfControl(FrameworkElement controlToConvert, ImageType imageType) { // return first frame of image var encoder = GetImageFromControl(controlToConvert, imageType); if (encoder != null && encoder.Frames != null && encoder.Frames.Count > 0) { return encoder.Frames[0]; } return new BitmapImage(); } /// <summary> /// Get an ImageSource of a control(Jpeg as default type) /// </summary> /// <param name="controlToConvert">The control to convert to an ImageSource</param> /// <returns>The returned ImageSource of the controlToConvert</returns> public static BitmapSource GetImageOfControl(FrameworkElement controlToConvert) { return GetImageOfControl(controlToConvert, ImageType.Jpeg); } /// <summary> /// Save an image of a control /// </summary> /// <param name="controlToConvert">The control to convert to an ImageSource</param> /// <param name="fileName">The location to save the image to</param> /// <returns>The returned ImageSource of the controlToConvert</returns> public static Boolean SaveImageOfControl(FrameworkElement controlToConvert, String fileName) { try { var imageType = GetImageTypeByFileName(fileName); using (var outStream = new FileStream(fileName, FileMode.Create)) { var encoder = GetImageFromControl(controlToConvert, imageType); encoder.Save(outStream); } } catch (Exception e) { Console.WriteLine("Exception caught saving stream: {0}", e.Message); return false; } return true; } public static BitmapImage ToBitmapImage(this BitmapSource bitmapSource) { var encoder = new JpegBitmapEncoder(); var memoryStream = new MemoryStream(); encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); encoder.Save(memoryStream); var bmp = new BitmapImage(); bmp.BeginInit(); bmp.StreamSource = new MemoryStream(memoryStream.ToArray()); bmp.EndInit(); memoryStream.Flush(); memoryStream.Close(); return bmp; } #endregion } }
GMap截图的效果图如下:
完美解决。