Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert System.Drawing.Icon to System.Media.ImageSource

I've got an IntPtr marshaled across an unmanaged/managed boundary that corresponds to an Icon Handle. Converting it to an Icon is trivial via the FromHandle() method, and this was satisfactory until recently.

Basically, I've got enough thread weirdness going on now that the MTA/STA dance I've been playing to keep a hosted WinForm from breaking the primary (WPF-tastic) UI of the application is too brittle to stick with. So the WinForm has got to go.

So, how can I get an ImageSource version of an Icon?

Note, I've tried ImageSourceConverter to no avail.

As an aside, I can get the underlying resource for some but not all of the icons involved and they generally exist outside of my application's assembly (in fact, they often exist in unmanaged dll's).

like image 485
Kevin Montrose Avatar asked Jul 14 '09 20:07

Kevin Montrose


2 Answers

Simple conversion method without creating any extra objects:

    public static ImageSource ToImageSource(this Icon icon)     {         ImageSource imageSource = Imaging.CreateBitmapSourceFromHIcon(             icon.Handle,             Int32Rect.Empty,             BitmapSizeOptions.FromEmptyOptions());          return imageSource;     } 
like image 140
Byte Avatar answered Oct 23 '22 04:10

Byte


Try this:

Icon img;  Bitmap bitmap = img.ToBitmap(); IntPtr hBitmap = bitmap.GetHbitmap();  ImageSource wpfBitmap =      Imaging.CreateBitmapSourceFromHBitmap(           hBitmap, IntPtr.Zero, Int32Rect.Empty,            BitmapSizeOptions.FromEmptyOptions()); 

UPDATE: Incorporating Alex's suggestion and making it an extension method:

internal static class IconUtilities {     [DllImport("gdi32.dll", SetLastError = true)]     private static extern bool DeleteObject(IntPtr hObject);      public static ImageSource ToImageSource(this Icon icon)     {                     Bitmap bitmap = icon.ToBitmap();         IntPtr hBitmap = bitmap.GetHbitmap();          ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(             hBitmap,             IntPtr.Zero,             Int32Rect.Empty,             BitmapSizeOptions.FromEmptyOptions());          if (!DeleteObject(hBitmap))         {             throw new Win32Exception();         }          return wpfBitmap;     } } 

Then you can do:

ImageSource wpfBitmap = img.ToImageSource(); 
like image 36
Kenan E. K. Avatar answered Oct 23 '22 02:10

Kenan E. K.