bluntsword

博客园 首页 联系 订阅 管理

    最近用GDIPlus做符号库,发现很多问题,nightware已经在一篇文章《GDI+的雷区 》中指出过http://blog.csdn.net/Nightmare/archive/2005/04/22/359092.aspx

    nightware说得很对,但我觉得还有一点必须提出来,GDIPlus使用float型,精度不够,在缩放比达到float的最小数值极限,问题就出来了,而在GIS程序中这个还是很容易碰到的。

    另外,提供了int型坐标的所有绘制方法应该都只是调用了float型坐标的方法,因为GDIPlus的绘制坐标都是世界坐标,int型此时只有做一个全部都用int型坐标的简单程序时才用得上,实际应用中,这种程序通常只是玩具。所以提供int型坐标是意义不大的。

    另外GDIPlus中还有很多的bug,比如下面一个例子,可能还是精度的问题,包括取样精度。scale小于168000f时,矩形、椭圆和直线都可以绘制出来、到168000f时,直线绘制不出来了,到169000f时,椭圆也出不来了。

float scale = 168000f;
float width = 100f / scale;

PointF pt = new PointF(100f, 100f);

RectangleF rect = new RectangleF(pt.X, pt.Y, width, width);

e.Graphics.TranslateTransform(pt.X, pt.Y);
e.Graphics.ScaleTransform(scale, scale);
e.Graphics.TranslateTransform(-pt.X, -pt.Y);

e.Graphics.FillRectangle(new SolidBrush(Color.Red), rect);
e.Graphics.FillEllipse(new SolidBrush(Color.Green), rect);
e.Graphics.DrawLine(new Pen(Color.Blue, 0), pt, new PointF(pt.X + width, pt.Y + width));

    提一下GDIPlus的绘制效率。我测试了5000个多边形,大约15M点数据。在VC下用GDI绘制大约450ms,C#用GDIPlus大约1450ms,VC下用OpenGL绘制只要几十毫秒。记得以前看过有人做过测试,但我找不到那篇文章了。

    要解决精度的问题,除非不用GDI+的坐标转换,整个绘制过程中保持世界坐标系和设备坐标系统一,然后自己记录实际坐标与设备坐标的缩放和偏移,然后在绘制时将实际坐标转换为设备坐标。以前用GDI就是这么干的,因为VC做这种计算很快,release下上面的15M数据只用20-30ms。但在C#中这个计算要200-300ms,太耗时间。

    总结下来,GDIPlus真的比较垃圾,不过做对精度和绘制效率要求不高的图形程序,用GDIPlus可以很容易做出很花的效果。

posted on 2005-08-10 11:34  钝刀重剑  阅读(3033)  评论(9编辑  收藏  举报