3. System.OutOfMemoryException
首先我们还是来看一段代码
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的有效性在函数的第一行就可以直接判断出来了,根本不需要到实际处理的时候才抛内存不足的异常。这个封装写得的确不怎么样。
(To be continued)