WPF控件到图片的转换
在实际的项目开发中,经常需要将信息保存成图片的形式,如屏幕截图、地图快照等操作,我中最近一个项目中便有这样的需求,项目(WPF)中用到GMap.NET控件,中地图上展示一些信息,过程中可能用户需要将地图信息保存下来,也就是地图快照,我的界面如下所示:
网上查了GMap相关的资料,没有找到GMap怎么截图的方法,最后找到网友提供的方法:将WPF控件转换成图片。
具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | 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截图的效果图如下:
完美解决。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步