1

I have an image control in my WPF application:

<Image x:Name="image" Source="{Binding}"/>

...and I'm trying to figure out which one would be the most efficient way of setting its source from an icon. I am using SystemIcons.WinLogo as my test subject.

First way involves CreateBitmpapSourceFromHIcon:

image.Source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(
                   SystemIcons.WinLogo.Handle, Int32Rect.Empty, 
                   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

The second approach uses BitmapImage and sets its source from the memory stream:

var ms = new MemoryStream();
SystemIcons.WinLogo.ToBitmap().Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
var bmpi = new BitmapImage();
bmpi.BeginInit();
bmpi.StreamSource = ms;
bmpi.EndInit();
image.Source = bmpi;

Which one should I use? They both work and I haven't noticed much difference in performance on my system.

B.K.
  • 9,982
  • 10
  • 73
  • 105
  • I usually go with the second approach. But that's mostly because I think my fellow programmers might find it a bit more readable should they ever be brave enough to hop out of C++ land and into C# land. – ouflak Mar 15 '14 at 08:28

1 Answers1

1

Both will serve the same purpose. If you ask me I would go with first approach because that's straight forward and no need to get icon first save in memory stream.

However, if you want to go with second approach make sure you call Freeze() on bitmapImage instance to avoid any memory leaks. Also freezing it will make it thread safe i.e. you can create a bitmapImage in background thread and can still set as Image source on UI thread.

var bmpi = new BitmapImage();
bmpi.BeginInit();
bmpi.StreamSource = ms;
bmpi.EndInit();
bmpi.Freeze(); <-- HERE
image.Source = bmpi;
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
  • Hmm, I didn't consider it before. That makes it thread safe, right? – B.K. Mar 15 '14 at 14:42
  • Yeah thread safe as well as avoid any memory leaks that might persist described [here](http://haozes.wordpress.com/2011/07/23/wpf-bitmapimage-memory-leak/) and [here](http://blogs.msdn.com/b/jgoldb/archive/2008/02/04/finding-memory-leaks-in-wpf-based-applications.aspx). – Rohit Vats Mar 15 '14 at 14:44
  • So, with the first method I wouldn't even have to worry about performance or memory leak? Or would I? – B.K. Mar 15 '14 at 17:42
  • I am aware of memory leak in case you manually generate bitMap using `Bitmap.GetHbitmap()` which is not the case in your's. [Reference](http://stackoverflow.com/questions/1546091/wpf-createbitmapsourcefromhbitmap-memory-leak). So, I think you can go ahead with first approach OR the updated second one mentioned above. Both should work perfectly for you. – Rohit Vats Mar 15 '14 at 17:54
  • 1
    Hmm, sounds like I would have to do some testing to see if the method I have generates any memory leaks. Either way, you've provided me with a lot of good information. Thank you very much! :) – B.K. Mar 15 '14 at 18:01
  • You know, I've been reading through the official documentation and many other posts and it seems that the first method is a bit unfavorable due to the unmanaged code. BitmapSource & BitmapImage were created to support WPF and XAML... so I think I'll stick with that route and take your advice on freezing. – B.K. Mar 15 '14 at 18:56