Wednesday, December 16, 2009

System.Drawing.Bitmap to fancy WPF BitmapSource

One of the big transitions that WPF (Windows Presentation Foundation) made away from the old GDI+ Windows Forms was the complete change to DirectX image formats.

Fortunately, Microsoft provide a nice little Interop method for this. Unfortunately, it's not that useful by itself.

The following .NET 3.5 extension methods convert either a System.Drawing.Image or System.Drawing.Bitmap to a System.Windows.Media.Imaging.BitmapSource.

/// 
    /// Contains extension methods for images.
    /// 
    public static class ImageExtensions
    {
        /// 
        /// Converts a  into a .
        /// 
        /// The source image./// A  containing the same image.
        public static BitmapSource ToBitmapSource(this System.Drawing.Image source)
        {
            System.Drawing.Bitmap bitmap = source as System.Drawing.Bitmap;
            if (bitmap != null) return bitmap.ToBitmapSource();

            bitmap = new System.Drawing.Bitmap(source);
            try
            {
                return bitmap.ToBitmapSource();
            }
            finally
            {
                bitmap.Dispose();
            }
        }

        /// 
        /// Converts a  into a .
        /// 
        /// The source bitmap./// 
        /// Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
        /// 
        /// A  containing the same image.
        public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
        {
            var hBitmap = source.GetHbitmap();

            try
            {
                return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
            catch (Win32Exception)
            {
                return null;
            }
            finally
            {
                NativeMethods.DeleteObject(hBitmap);
            }
        }
    }

Enjoy!

No comments:

Post a Comment