2010-03-12 94 views
5

我有一個第三方的DLL生成一個位圖併發回它的引用。如果我立即生成一個System.Windows.Media.Imaging.BitmapSource,那麼一切順利。但是,如果我救了參考和以後(幾秒鐘,許多函數調用後),我嘗試生成的BitmapSource,我得到跨類庫傳遞System.Drawing.Bitmap不可靠?

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()); 

上怎麼回事錯在這裏任何線索?任何指針都會有用。謝謝。

回答

3

我有位圖和訪問衝突的一個大問題也。我認爲會發生的事情是某些位圖構造函數在不應該時打開文件句柄。因此,您正在運行的程序會檢測到文件正在使用,但不應該是。

我終於想通了,在一個解決方案,我使原來的位圖的副本,然後丟棄原。這裏是我的代碼,它保留了原來的位圖的分辨率:

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; 

顯然,對於第一線,你將位圖溫度= MyThirdPartyDLL.GetBitmap();或者其他的東西。如果你不關心它的分辨率可以簡化爲:

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

進行此更改後,我能夠做各種文件I/O等,完全沒有問題,希望你能做到相同。

+0

對不起,它與文件句柄沒有任何關係。請參閱Andras的答案以獲得正確的解釋。不過,我確實喜歡你的解決方案,以複製一個位圖來解決bug(+1)。如果mishal153的內部數據結構需要Bitmap而不是BitmapSource,則應使用您發佈的代碼。如果沒有,他會更好地服務,只需立即創建BitmapSource而不是創建一個新的位圖。 – 2010-03-13 18:07:53

+1

嗨布蘭迪, 你的建議作品像一首歌:)。謝謝! 我試圖做同樣的事情,但我這樣做的方式是:'newBmp = oldBmp.Clone(); '克隆文檔說「創建一個精確的副本這個圖像。」,所以我認爲我做了深層複製。 什麼是真正令人困惑的是,位圖的構造的文件說,「初始化從指定的現有圖像Bitmap類的新實例」,那聽起來像它只是包裝現有的圖像,當INFACT它做深複製:)。它只有我或者是這也讓別人感到困惑。 謝謝你們 – mishal153 2010-03-15 12:06:16

+0

很高興能有所幫助。 :) – Brandi 2010-03-15 14:37:49

4

我認爲這表明由bmp.GetHBitmap返回的句柄(引用由操作系統管理的資源,而不是.Net)不再有效 - 可能Dispose已被調用某處或類似的東西(不一定按你的代碼雖然)。

我建議你堅持使用不依賴於手柄的位圖數據的另一種方式 - 可能流出來的位圖本身的二進制數據馬上,然後扔到一個參考各地。