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, 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,很容易你就会遇到这个问题。

(To be continued)

[1]. Microsoft Security Bulletin MS04-028 Buffer Overrun in JPEG Processing (GDI+) Could Allow Code Execution (833987) http://www.microsoft.com/technet/security/bulletin/MS04-028.mspx

[2].Microsoft Security Bulletin MS08-052 – Critical Vulnerabilities in GDI+ Could Allow Remote Code Execution (954593) http://www.microsoft.com/technet/security/bulletin/MS08-052.mspx

时间: 2024-09-03 15:56:24

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

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+中常见的几个问题(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