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截图的效果图如下:

完美解决。

posted on 2015-11-07 23:16  WangAnuo  阅读(1371)  评论(0编辑  收藏  举报