`
cloudtech
  • 浏览: 4605933 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

使用GDI+进行开发的一些问题(3)

 
阅读更多

问题3,为啥读个图那么慢?

一般来说,读图可以用以下几种方法:

publicstaticImage FromFile(string filename);
publicstaticImage FromFile(string filename,bool useEmbeddedColorManagement);
publicstaticBitmap FromHbitmap(IntPtr hbitmap);
publicstaticBitmap FromHbitmap(IntPtr hbitmap,IntPtr hpalette);
publicstaticImage FromStream(Stream stream);
publicstaticImage FromStream(Stream stream,bool useEmbeddedColorManagement);
publicstaticImage FromStream(Stream stream,bool useEmbeddedColorManagement,bool validateImageData);

其中3,4两种方法主要用在从Windows句柄中拿到原来DIB的Bitmap,经常是用在需要读取资源图像啊,或者GDI图像的时候。最经常用的,无非是1,2和5,6,7,其中1和5类似,2和6类似,方法5,6会使用不同的参数调用7。我们可以做一个简单的性能测试。拿一张8000*7000大的TIF图像,这样的图像一般大小都在100M以上,用下面四种不同的参数调用方法7:

//Use ICM:true, Validation: true
Stopwatch watch =newStopwatch();
watch.Start();
FileStream fs =newFileStream(image,FileMode.Open,FileAccess.Read);
Image img =Image.FromStream(fs,true,true);
Console.WriteLine("Use ICM: {0}. Validate:{1}, ElapsedTicks:{2}.", true,true, watch.ElapsedTicks);
watch.Stop();
fs.Close();

//Use ICM:false, Validation: true
Stopwatch watch =newStopwatch();
watch.Start();
FileStream fs =newFileStream(image,FileMode.Open,FileAccess.Read);
Image img =Image.FromStream(fs,false,true);
Console.WriteLine("Use ICM: {0}. Validate:{1}, ElapsedTicks:{2}.", false,true, watch.ElapsedTicks);
watch.Stop();
fs.Close();

//Use ICM:true, Validation: false
Stopwatch watch =newStopwatch();
watch.Start();
FileStream fs =newFileStream(image,FileMode.Open,FileAccess.Read);
Image img =Image.FromStream(fs,true,false);
Console.WriteLine("Use ICM: {0}. Validate:{1}, ElapsedTicks:{2}.", true,false, watch.ElapsedTicks);
watch.Stop();
fs.Close();

//Use ICM:false, Validation: false
Stopwatch watch =newStopwatch();
watch.Start();
FileStream fs =newFileStream(image,FileMode.Open,FileAccess.Read);
Image img =Image.FromStream(fs,false,false);
Console.WriteLine("Use ICM: {0}. Validate:{1}, ElapsedTicks:{2}.", false,false, watch.ElapsedTicks);
watch.Stop();
fs.Close();

我们来看看执行结果:

Use ICM: True. Validate: True, ElapsedTicks:51853544.
Use ICM: False. Validate: True, ElapsedTicks:52507953.
Use ICM: True. Validate: False, ElapsedTicks:6880.
Use ICM: False. Validate: False, ElapsedTicks:5187.

所以你看到,罪魁祸首是Validate。当然Validate其实是有用的,图像的格式各种各样,就单BMP就有好多种不同的放法,更不要说JPEG, PNG, GIF了。JPEG有最早的用离散余弦变换生成的,还有用小波变换生成的JPEG 2000。PNG没啥研究,不知道里面什么名堂。GIF有静态的和能动的GIF 98.所以后面的数据流出问题是很正常的事情,验证在很多情况下是需要的,但是造成的性能损失实在是很大。如果你确定这些照片一般不会错,而且读图又需要很好的性能,比如获得一个目录里面所有图像的缩略图,那还是用最后一种方法吧。


这里再提一下ICM。ICM是色彩管理中的一个概念,对于相同图像不同设备而言,呈现的色彩可能是不同的。比如一个液晶显示器和一个CRT显示器,先是一张相同的图片,色彩可能相差十万八千里。这主要是因为不同设备能够显示的色彩空间是不同的。色彩空间又是个值得研究的话题,这里就不多说了。对于色彩的研究可以写一本很厚的书。这个世界上最权威的一个网站http://www.color.org 可以告诉你很多有用的信息和数学公式,包括Gamma,色彩密度的概念,等等诸如此类。有些图像格式是可以把ICM的信息写在文件中的,比如JPEG。所以这个参数是说是否使用文件内嵌的ICM信息还是用设备默认的信息。


其实第7个函数是在.NET 2.0以后才出现的。1.1出来以后读图慢的这个问题被别人骂得要死,所以新版本中加了一个函数解决了这个问题。当时有个叫Justin Rogers的人写了个类叫ImageFast (http://weblogs.asp.net/justin_rogers/articles/131704.aspx),自己用Interop去调用GDI+的方法,跳过了icm和validation。在.NET 2.0之后,这个问题才算是被解决了。这又是.NET Framework对GDI+封装不完善的一个例子。

分享到:
评论

相关推荐

    GDI+开发包 GDI+ SDK

    GDI+开发包,解压文件,并将其中的Includes和Lib中的文件复制到VS安装目录中VC98目录下的Includes和Lib文件夹中

    GDI+开发包 GDI+安装详解

    Visual C++6.0使用GDI+的一般方法 1. 载解压GDI+开发包; 2. 正确设置include & lib 目录; 3. stdafx.h 添加: #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #endif #include 或者 将Visual...

    gdi+ 帮助文档

    对于初学者,还有一个问题就是,如果想要进行GDI+开发, 需要下载一个GDI+的开发包(SDK). 网上搜到的一般只包含一个DLL,没法用. 在我另外一个资源中提供了一个详细的SDK,包含了进行开发所需要的全部内容:头文件,库文件...

    GDI+开发库

    GDI+开发库

    GDI+图像程序设计(PDF & 源码 -电子工业出版社)

     本书从介绍GDI+Windows图形程序设计的基本知识开始,其核心是对一些实际问题的指导,包括如何使用Windows Forms及如何优化GDI+的性能。本书通过一些例子来说明如何开发真实世界的工具,如GDI+Painter、GDI+Editro...

    GDI+库以及使用方法

    1. 载解压GDI+开发包; 2. 正确设置include & lib 目录; 3. stdafx.h 添加: #ifndef ULONG_PTR #define ULONG_PTR unsigned long* #endif #include 4. 程序中添加GDI+的包含文件gdiplus.h以及附加的类库...

    GDI+开发包

    包含GDI+开发所必需的开发包,并且包括配置使用方法,

    VC下如何使用GDI+进行

    因为GDI+对GDI的很多性能进行了优化,同时还提供了其他的一些特性。 一个图形设备接口,例如GDI+, 允许应用程序开发人员在打印机或屏幕上显示信息,而不用去考虑显示设备的具体细节。应用程序开发人员调用GDI+ ...

    C#GDI+图形程序设计源码

    2.4 一些基本的GDI+ 对象 总结 第3章 Graphics类 3.1 Graphics类的属性 3.2 Graphics类的方法 3.3 GDI+ Painter应用程序 3.4 绘制饼图 总结 第4章 使用画笔和钢笔 4.1 理解和使用画笔 4.2 在GDI+ 中使用...

    使用vc和gdi+开发图形界面

    使用VC6和GDI+开发图形界面.首先在VC6加载GDI+动态库,然后根据自己的要求建立控件,在控件中使用GDI+绘图.使用GDI+比使用GDI思路更清晰,界面更美观.

    GDI+库文件

    顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,...

    GDI+ PDF.rar

    顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,Windows XP仍然支持以前版本的GDI,但是在开发新应用程序的时候,开发人员为了满足图形输出需要应该使用GDI+,因为GDI+对以前的Windows版本中GDI进行了优化,...

    GDI+ SDK参考(翻译版本)_gdi+_源码

    GDI+SDK开发手册 翻译版本,GDI+详细开发说明

    GDI+ 开发SDK

    GDI+的开发组件,包括了所有的头文件,动态链接库文件和lib文件

    GDI+开发资料

    GDI+开发资料 类库及说明文档

    GDI+油量表开发

    GDI+油量表开发

    VC中使用GDI+库,实现图片旋转

    基于VC++语言,VS平台开发,应用GDI+库,双缓冲,实现图片旋转,屏幕不闪烁。代码量不大,简单易学。

    GDI+程序设计_GDI+程序设计_

    一本为C#开发人员准备的图形图像处理技术的书籍

Global site tag (gtag.js) - Google Analytics