在WPF中使用图像控件显示System.Drawing.Bitmap

76

我如何在WPF中将内存中的Bitmap对象分配给Image控件?


这是一个与https://dev59.com/1XVD5IYBdhLWcg3wE3bz完全相同的问题,但我的答案不会泄漏HBitmap。 - Lars Truijens
这个回答解决了你的问题吗?从System.Drawing.Bitmap加载WPF BitmapImage - StayOnTarget
4个回答

86

根据http://khason.net/blog/how-to-use-systemdrawingbitmap-hbitmap-in-wpf/的说法

   [DllImport("gdi32")]
   static extern int DeleteObject(IntPtr o);

   public static BitmapSource loadBitmap(System.Drawing.Bitmap source)
   {
       IntPtr ip = source.GetHbitmap();
       BitmapSource bs = null;
       try
       {
           bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip, 
              IntPtr.Zero, Int32Rect.Empty, 
              System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
       }
       finally
       {
           DeleteObject(ip);
       }

       return bs;
   }

它获取来自WindowsBased的System.Drawing.Bitmap并将其转换为BitmapSource,这可以实际用作WPF中Image控件的图像源。

image1.Source = YourUtilClass.loadBitmap(SomeBitmap);

7
谢谢,Lars。不过我做了更简单的方式:BitmapImage bmpi = new BitmapImage(); bmpi.BeginInit(); bmpi.StreamSource = new MemoryStream(ByteArray); bmpi.EndInit(); image1.Source = bmpi; - Prashant Cholachagudda
4
好的,你可以将你的解决方案作为答案添加到你自己的问题中。 - Lars Truijens
我没有看到BitmapImage.StreamSource方法。Prashant,你打错了吗? - Patrick Szalapski
4
使用未管理的句柄(例如HBITMAP)时,建议考虑使用SafeHandles。详情请参见https://dev59.com/7nI_5IYBdhLWcg3wDOnW#7035036 - Jack Ukleja
@Lars Truijens 非常棒,我从来没有想过那个方法。 - Oli
显示剩余2条评论

17

对于磁盘文件来说很容易,但对于内存中的位图则更加困难。

System.Drawing.Bitmap bmp;
Image image;
...
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();

image.Source = bi;

从这里摘录


谢谢,但代码没有关闭 ms。我认为您可以使用 https://dev59.com/1XVD5IYBdhLWcg3wE3bz#1069509。 - lindexi
@lindexi 即使 MemoryStream 实现了 IDisposable 接口,但它不需要显式地被释放,因为它没有包装任何非托管资源。它就像一个字节数组,最终会被 GC 回收。 - kennyzx

17
你可以使用图像的Source属性。尝试这段代码...
ImageSource imageSource = new BitmapImage(new Uri("C:\\FileName.gif"));

image1.Source = imageSource;

2
我有一个Bitmap对象,实际上它是从扫描设备生成的,所以我无法引用任何位置。 - Prashant Cholachagudda

2

我用 wpf 写了一个程序,使用数据库来显示图片,以下是我的代码:

SqlConnection con = new SqlConnection(@"Data Source=HITMAN-PC\MYSQL;
                                      Initial Catalog=Payam;
                                      Integrated Security=True");

SqlDataAdapter da = new SqlDataAdapter("select * from news", con);

DataTable dt = new DataTable();
da.Fill(dt);

string adress = dt.Rows[i]["ImgLink"].ToString();
ImageSource imgsr = new BitmapImage(new Uri(adress));
PnlImg.Source = imgsr;

3
不错的回答,但我强烈建议将Sql对象包装在using语句中,这样它们在使用完毕后就会被处理掉。 - Maurice Reeves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接