跨类库传递System.Drawing.Bitmap是不可靠的?

时间:2010-03-12 14:50:02

标签: c# wpf bitmap

我有一个第三方dll,它会生成一个Bitmap并发回它的引用。如果我立即生成一个System.Windows.Media.Imaging.BitmapSource,那么一切顺利。但是如果我保存引用并稍后(几秒钟之后和许多函数调用)我尝试生成Bitmapsource,我得

  

System.AccessViolationException是   未按用户代码处理
  消息=尝试读取或写入   受保护的记忆这通常是一个   表明其他记忆是   腐败。源= “System.Drawing中”

做的时候:

System.Windows.Media.Imaging.BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
    bmp.GetHbitmap(),
    IntPtr.Zero,
    Int32Rect.Empty,
    System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());

关于这里出错的任何线索?任何指针都会很有用。感谢。

2 个答案:

答案 0 :(得分:4)

我认为这表明由bmp.GetHBitmap返回的句柄(对操作系统管理的资源的引用,而不是.Net)不再有效 - 可能已在某处调用Dispose或类似的东西(不一定是你的代码。)

我建议使用另一种方法来持久化不依赖于句柄的位图数据 - 可能会立即流出位图本身的二进制数据,然后抛出对它的引用。

答案 1 :(得分:3)

我在Bitmaps和访问冲突方面遇到了很大问题。我认为发生的事情是某些位图构造函数在不应该打开文件句柄时保持打开状态。因此,您运行的程序会检测到文件正在使用,而不应该使用。

我最终找到了一个解决方案,我制作原始位图的副本然后处理原始位图。这是我的代码,它保留了原始位图的分辨率:

Bitmap Temp = new Bitmap(inFullPathName);
Bitmap Copy = new Bitmap(Temp.Width, Temp.Height);
Copy.SetResolution(Temp.HorizontalResolution, Temp.VerticalResolution);
using (Graphics g = Graphics.FromImage(Copy))
{
     g.DrawImageUnscaled(Temp, 0, 0);
}
Temp.Dispose();
return Copy;

显然,对于第一行,你的是Bitmap Temp = MyThirdPartyDLL.GetBitmap();或者其他的东西。如果您不关心分辨率,可将其简化为:

Bitmap Temp = MyThirdPartyDLL.GetBitmap();
Bitmap Copy = new Bitmap(Temp, Temp.Width, Temp.Height);
Temp.Dispose();
return Copy;

进行此更改后,我能够完成所有类型的文件I / O等,非常好,希望您也可以这样做。