3. System.OutOfMemoryException
首先我們還是來看一段代碼
Bitmap bmpTemp = new Bitmap(image);
Bitmap bmp = new Bitmap(bmpTemp);
bmpTemp.Dispose();
Bitmap bmp2 = bmp.Clone(new Rectangle(1, 1, bmp.Width, bmp.Height), PixelFormat.Format24bppRgb);
前一段我們還是使用了在第2節中介紹的讀圖像文件的方法,之後我們使用Bitmap.Clone ()方法復制一份拷貝。其實這是除了new Bitamp()之外的另一種復制圖像的方法。這個方法 強大的地方是它可以復制圖像的一塊區域。不幸的是上面那句話會給你一個 System.OutOfMemoryException。這個Exception索性連ErrorCode都不給你了, innerException還是空。Krzysztof Cwalina和Brad Abrams寫過一本叫"Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries",不幸的是我們的System.Drawing下面的多個類都不符合這本書寫的內容。 說到這本書,中文版還是我一個同事翻譯的,做一把廣告。 (http://www.amazon.cn/mn/detailApp?qid=1224568025&ref=SR&sr=13- 2&uid=168-7715813-6370648&prodid=zjbk366428)
那麼這個問題到底是為什麼呢?我們再用Marshal.GetLastWin32Error() 來看看錯誤所在 。可惜這次不靈了,我們拿到了一個2的錯誤代碼,在winerror.h裡,它是
//
// MessageId: ERROR_FILE_NOT_FOUND
//
// MessageText:
//
// The system cannot find the file specified.
//
#define ERROR_FILE_NOT_FOUND 2L
完全沒有什麼關系。細心的讀者可能已經發現了,我在Rectangle裡面傳遞的參數是1,1 ,而不是0,0。這也就是說這個矩形已經超過了原始圖像的大小。所以會報這個異常。但是 是不是應該報OutOfMemory呢?讓我們再看看MSDN.上面倒是說的很清楚,如果rect區域超出 ,報OutOfMemory,如果rect寬或者高是0,那麼報ArgumentException. 為什麼不統一成一個 ArgumentException呢?很費解。 其實Rect的有效性在函數的第一行就可以直接判斷出來了 ,根本不需要到實際處理的時候才拋內存不足的異常。這個封裝寫得的確不怎麼樣。