GDI+一般性錯誤(A generic error occurred in GDI+)


1.GDI+的前世今生

GDI+全稱圖形設備接口,Graphics Device Interface (GDI) ,他的爸爸叫做GDI, 用C寫的。Windows XP出來以后用C++重新寫了一下,變成了GDI+。從.NET Framework 1.0開始,GDI+就被正式封裝在了.NET Framework里面,並被廣泛地應用到了所有和圖形圖像相關的程序中。不幸的是,這個GDI+引入了微軟有史以來最大的2個patch,造成了Microsoft IT, Support, Developer, Tester的無數麻煩。[1][2]

GDI+沒有用顯卡加速,所以Windows Vista推薦用Windows Display Driver Model (WDDM)了,支持渲染,3D加速。不過普通的應用程序,用GDI/GDI+其實是完全足夠了,所以GDI+是在微軟平台上開發圖形圖像程序的最好選擇了。至少現在沒有聽說微軟准備重新寫GDI

GDI+ 可以用來做圖形處理,也可以做圖像處理。這里只分析幾個使用.NET Framework容易出錯的地方。 

2. GDI+一般性錯誤(A generic error occurred in GDI+)

這是使用GDI+的時候最滑稽的一個Exception,里面啥信息都沒有。對於剛剛開始使用.NET Framework開發者來說,很難發現這個問題到底是為什么。

我們先來看看下面一段代碼 

 

string fileName = "sample.jpg";
Bitmap bmp = new Bitmap(fileName);
bmp.Save(fileName, ImageFormat.Jpeg);

這段代碼的目的是要打開一個Bitmap,然后保存。可惜這段代碼一定會給你一個GDI+一般性錯誤:

System.Runtime.InteropServices.ExternalException

其中的Error Code是0x80004005, innerException是空。如果你查Windows的Error Code表,會發現這個錯誤原因是“Unspecified Error”,還是什么都不知道。這其實是.NET Framework封裝不好的問題,我們可以調用

Marshal.GetLastWin32Error()

拿到Win32的Error, 32。這個錯誤代碼就有點信息量了,在winerror.h里面,我們可以找到下面的定義:

復制代碼
//
// MessageId: ERROR_SHARING_VIOLATION
//
// MessageText:
//
//  The process cannot access the file because it is being used by another process.
//
#define ERROR_SHARING_VIOLATION          32L
復制代碼

  

原來是文件不能寫。其實MSDN里面有一句話,The file remains locked until the Bitmap is disposed。所以文件讀取以后是鎖着的,沒有辦法寫。那如果我想做點改動然后再保存原來的文件怎么辦呢?

這里有個土辦法可以搞定這個問題 

Bitmap bmpTemp = new Bitmap(image);
Bitmap bmp = new Bitmap(bmpTemp);
bmpTemp.Dispose();
bmp.Save(image, ImageFormat.Jpeg);

 

只要把當前的圖像復制一份,然后把舊的Dispose掉,那個文件就不被鎖住了,這樣就可以放心覆蓋原始文件了。

想想如果你要用GDI+寫一個Painter,很容易你就會遇到這個問題。 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM