WPF – 将Bitmap转换为ImageSource

我需要将System.Drawing.Bitmap转换为System.Windows.Media.ImageSource类,以便将其绑定到WizardPage(扩展WPF工具包)的HeaderImage控件中。 位图设置为我编写的程序集的资源。 它被引用如下:

public Bitmap GetBitmap { get { Bitmap bitmap = new Bitmap(Resources.my_banner); return bitmap; } } public ImageSource HeaderBitmap { get { ImageSourceConverter c = new ImageSourceConverter(); return (ImageSource) c.ConvertFrom(GetBitmap); } } 

这个转换器是我在这里找到的: http : //www.codeproject.com/Questions/621920/How-to-convert-Bitmap-to-ImageSource我得到一个NullReferenceException

return (ImageSource) c.ConvertFrom(Resources.my_banner); 如何初始化ImageSource以避免此exception? 或者还有另一种方式吗? 我希望之后使用它:

  <xctk:WizardPage x:Name="StartPage" Height="500" Width="700" HeaderImage="{Binding HeaderBitmap}" Enter="StartPage_OnEnter" 

提前感谢您的任何答案。

对于其他人,这有效:

  //If you get 'dllimport unknown'-, then add 'using System.Runtime.InteropServices;' [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteObject([In] IntPtr hObject); public ImageSource ImageSourceForBitmap(Bitmap bmp) { var handle = bmp.GetHbitmap(); try { return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } finally { DeleteObject(handle); } } 

为了搜索者的利益,我基于这个更详细的解决方案创建了一个快速转换器。

到目前为止没问题。

 using System; using System.Drawing; using System.IO; using System.Windows.Media.Imaging; namespace XYZ.Helpers { public class ConvertBitmapToBitmapImage { ///  /// Takes a bitmap and converts it to an image that can be handled by WPF ImageBrush ///  /// A bitmap image /// The image as a BitmapImage for WPF public BitmapImage Convert(Bitmap src) { MemoryStream ms = new MemoryStream(); ((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); BitmapImage image = new BitmapImage(); image.BeginInit(); ms.Seek(0, SeekOrigin.Begin); image.StreamSource = ms; image.EndInit(); return image; } } } 

我不相信ImageSourceConverter会从System.Drawing.Bitmap转换。 但是,您可以使用以下内容:

 public static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap) { if (bitmap == null) throw new ArgumentNullException("bitmap"); var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var bitmapData = bitmap.LockBits( rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); try { var size = (rect.Width * rect.Height) * 4; return BitmapSource.Create( bitmap.Width, bitmap.Height, bitmap.HorizontalResolution, bitmap.VerticalResolution, PixelFormats.Bgra32, null, bitmapData.Scan0, size, bitmapData.Stride); } finally { bitmap.UnlockBits(bitmapData); } } 

该解决方案要求源图像采用Bgra32格式; 如果您正在处理其他格式,则可能需要添加转换。

dethSwatch – 谢谢你的答案! 它帮助极大! 在实现它之后,我得到了理想的行为,但我发现我在程序的另一部分中遇到了内存/句柄问题。 我将代码更改为如下,使其更加冗长,问题就消失了。 再次感谢你!

  [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteObject([In] IntPtr hObject); public ImageSource ImageSourceForBitmap(Bitmap bmp) { var handle = bmp.GetHbitmap(); try { ImageSource newSource = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); DeleteObject(handle); return newSource; } catch (Exception ex) { DeleteObject(handle); return null; } } 

对我来说最简单的解决方案:

 ImageBrush myBrush = new ImageBrush(); var bitmap = System.Drawing.Image.FromFile("pic1.bmp"); Bitmap bitmap = new System.Drawing.Bitmap(image);//it is in the memory now var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(),IntPtr.Zero,Int32Rect.Empty,BitmapSizeOptions.FromEmptyOptions()); myBrush.ImageSource = bitmapSource; cover.MainGrid.Background = myBrush; cover.Show(); bitmap.Dispose();