GDI+中常见的几个问题(2)

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的有效性在函数的第一行就可以直接判断出来了 ,根本不需要到实际处理的时候才抛内存不足的异常。这个封装写得的确不怎么样。

时间: 2024-10-31 01:13:37

GDI+中常见的几个问题(2)的相关文章

GDI+中常见的几个问题(10)

10. Graphics的几个属性. 今天我来讲讲Graphics在DrawImage里的几个的属性. Graphics是GDI+里面的大拿,可以用来画线,画矩形,甚至可以用来画各种各样的材质. 通过不同的Pen,Brush来实现.具体的使用方法是所有想用GDI+的同学的基础,我就不详细讲 了,具体可以参考MSDN:http://msdn.microsoft.com/en-us/library/haxsc50a(VS.80).aspx .我主要来讲2个大家不太注意的属性. a.Graphics.

GDI+中常见的几个问题(9)

今天来讲讲上个星期遗留下来的东西:ColorMatrix. 9. Color Matrix 图像的本质是什么?对不同的人来说这是不同的东西.在计算机的世界中,啥东西都是数 据,图像也是一种数据.从自然界的光变成计算机的数据,需要通过采样和量化的处理.图 像在计算机中,其实是一个二维数组,从数学上来说,这其实是一个矩阵.图像中的每一个 点都是个四维向量,也就是(R,G,B,A), 在RGBA色彩空间中,我们可以使用一个矩阵对每一 个点(R,G,B,A)作矩阵乘法运算,这样就可以对图像色彩进行变换.

GDI+中常见的几个问题(8)

哈哈,这个星期Heroes第八集终于出来了,我继续顺着上一节外传讲下去,修改颜色怎么 做. 8.1 使用原始的方法修改图像的RGB以及色调,饱和度和亮度 最简单的办法,很容易,就是用之前的LockBits,然后直接修改R,G,B的数值,具体的就 不多说了.在GDI+里面,Color有3个方法,分别是GetHue(), GetSaturation(), GetBrightness().它是图像的色调,饱和度和亮度.其中Hue取值为[0,360),表示当前颜色 在哪一个角度,Saturation和B

GDI+中常见的几个问题(7)

7. 多帧图像 为了赶上英雄第三季的播放日程,我决定一个星期出一集. 在第七集Heroes里面,Peter 的功能都被他老爸吸收掉了.所以我的这个系列的第七集来讲讲GDI+没完全实现的一部分功 能. 多帧图像是指在一幅图像中有多个帧,支持多帧图像的格式不多,只有TIFF和GIF.其他 格式都不能作为多帧图像存储.其中TIFF可以支持很多页,GIF动画也支持多帧.使用GDI+可 以生成多帧TIFF,却没办法实现GIF动画的生成,有可能是因为专利的缘故.首先让我们来看 看怎么样在生成多帧的TIFF图

GDI+中常见的几个问题(5)

6.透明,半透明和不透明 这是个大题目.在WinForm/WPF里面我们经常会看到一些关于透明的属性,比如Backcolor 里面可以选择Transparant, Form里面有一个叫Opacity的属性.都是和透明以及透明度相关 的.在其实是在GDI+应用层上的一些东西,在这里我就不讲了.主要从更基本的地方讲起, 其中还包括两块完全不同的内容. 6.1 Alpha 我们在上一讲中提到了PixelFormat,当时我们在LockBits的时候把PixelFormat设定成为 Format24bp

GDI+中常见的几个问题(3)

4. 为啥读个图那么慢? 一般来说,读图可以用以下几种方法: 1 public static Image FromFile(string filename); 2 public static Image FromFile(string filename, bool useEmbeddedColorManagement); 3 public static Bitmap FromHbitmap(IntPtr hbitmap); 4 public static Bitmap FromHbitmap (

GDI+中常见的几个问题(1)

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

GDI+中常见的几个问题(11)

我在前面几章里面提到过ColorMatrix,可以将图像的色彩进行仿射变换.但是如果要对图 像的色彩进行非线性变换的话,那就必须用到更强悍的API了.在Windows早期,有一套标准 的色彩管理的API,叫做ICM 2.0 (Image Color Management 2.0).在Windows Vista 以后, 这套API升级成了WCS 1.0 (Windows Color System 1.0). 这套API实现了www.color.org 上说的色彩管理的算法,具体的内容在http:/

GDI+中常见的几个问题(8.外传1)

8. 颜色修正 我最近一直在颜色空间中纠结,前面讲的透明不透明只是一种特殊的颜色.今天我准备要 讲的是真正的修正颜色.我们使用的数码相机有不同的型号,感光的CCD性能也是不一样的, 再加上天气或者周围光线的原因,我们排出来的照片可能会偏色.此外,为了做一些特殊处 理,可能需要将照片中某一个特殊的区域颜色进行修正.比如脸色可以变得更好一点,或者 头发更黑一点等等.这个Topic很大,我会花好几个星期来讲这些内容,因为涉及到许多图像 处理的基本知识.今天咱们不写code,只讲理论(谁让这个星期美国大

GDI+中常见的几个问题(6)

6.2 GIF GIF的全称是图像交换格式Graphics Interchange Format,是CompuServe公司在1987年创 建并使用的.这种格式使用8位索引值来表达一个像素,也就是说1个像素1个byte,最多可以 表示256种颜色.它使用LZW无损压缩算法来对图像进行压缩,之后这家公司又和几家其他的 公司发明了PNG文件格式,并被更广泛地应用在Web以及其他领域.GIF支持动画,可以保存数 个帧并不断地播放.关于动画的部分我们将会放到非常后面来讲,现在只谈谈GIF的透明. 在GI