5.读图是快了,处理怎么还是慢?
GDI+的Bitmap类提供了两个罪恶的函数GetPixel, SetPixel,用来获取某个像素点的颜色值。这个2个函数如果只调用一次两次也就罢了,万一我想把整张图片加红一点,用下面的代码,我估计你等到黄花菜都凉了,还没有算完呢。 看看下面的代码是怎么写的。
1 FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
2 Image img = Image.FromStream(fs, false, false);
3 Bitmap bmp = new Bitmap(img);
4 img.Dispose();
5 fs.Close();
6
7 for (int j = 0; j < bmp.Height; j++)
8 {
9 for (int i = 0; i < bmp.Width; i++)
10 {
11 Color color = bmp.GetPixel(i, j);
12 color = Color.FromArgb(color.R + 20, color.G, color.B);
13 bmp.SetPixel(i, j, color);
14 }
15 }
代码逻辑很清楚,第1到第5行,写得很好,用了我们在前几节里面的方法,读图速度飞快且不锁文件。当然如果不用覆盖原始文件,不用复制都可以,速度就更快了。接下来我们对图像做一个循环,一行一行更新图像的数据。殊不知GetPixel和SetPixel是GDI里面耗费最大的函数之一,此外bmp.Height和bmp.Width也是慢得够呛,如果处理一张500M像素的照片,您可以去喝杯茶,睡一觉再回来了。
Bitmap有个方法叫LockBits,就是把图像的内存区域根据格式锁定,拿到那块内存的首地址。这样就可以直接改写这段内存了。这个方法的设计是挺好,可惜都是C++作为源泉来的,.NET Framework里面根本就不推荐用指针,VB里面根本也就没有指针。最后设计了一个鸡肋的IntPtr,将就掉了这个问题。C#其实还好,可以用unsafe code,也算是间接用了指针,VB.NET就痛苦了,需要用Marshal.Copy把内容Copy到一个byte数组里面,然后处理完了再Copy回去。所以结论就是,要用GDI+做图像处理,最好别用VB.NET,否则内存翻倍。
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!