介绍和推荐AGG

介绍和推荐AGG

    最近在研发跨平台的GIS engine,GDI部分当然不能只用WINDOWS的GDI PLUS,一个跨平台的 2D Engine 的选择就非常重要。网上查了N久,感觉AGG非常全面,效果也很好,而且也是跨平台的。非常适合我的问题领域。   

一、AGG是什么
      AGG,全名:Anti-Grain Geometry,是一个开源的、高效的2D图形库,它的网站:
http://www.antigrain.com/

二、AGG的特点
      AGG的功能与GDI+的功能非常类似,但提供了比GDI+更灵活的编程接口,其产生的图形的质量也非常高,而且它是跨平台的,其宣传可以在非常多的操作系统上运行,我至少在Windows、Wince、Linux三个台平上测试通过。

三、AGG的功能
1、支持ALPHA、GAMMA等变色处理,以及用户自定义的变色处理;
2、支持任意2D图形变换;
3、支持SVG和PostScript描述,适于网上图形生成;
4、支持高质量的图形处理,支持反走样插值等高级功能;
5、支持任意方式的惭变色处理;
6、支持所有颜色格式;
7、支持对位图的多种处理;
8、支持直线的多种处理,类似于GDI+;
9、支持GPC,即通用多边形裁剪方法;
10、支持多种字体输出,包括汉字的处理;

四、AGG的使用
     在设计上,它是师出Boost库,在其中使用了大量的现代标准C++语言的语法规则,包括模板、仿函数等处理,但是为了能在更多的平台上使用,它并没有直接使用Boost和STL库,而是自己实现了部分STL功能。
     AGG将图形功能分为几个层次,每一层次都可以由用户自己改动和扩充,作为AGG的使用者,可以使用它的全部功能,也可以只使用它的部分功能;作为图形的接口,它允许用户在不同层次上对它进行访问。
   以下是一个典型的作图分层:
1、定义矢量作图源数据(其定义类似于PostScript);
2、提供变换管道(包括坐标变换,以及其它可能的数据变换);
3、将数据转为水平线光删化数据;
4、将数据转为带颜色格式的输出缓冲区数据;
5、输出位图或象素数组。
     AGG的设计定位是为其它开发工具提供工具,因此,其使用是灵活但不容易,但通过它提供的几十个例子,可以很容易地入门(但精通不是易事)。
     为了使用AGG,有两种方式,一种方式是直接使用它,一种方式是为它定义一个封装接口。现在网上有一些这方面的封装接口例子(比如说,定义一个仿GDI+ 的封装接口),可以在它的论坛上找到。本人也编写了一个封装类组,但主要是为了我的项目用的,以后我会提供一个更通用的封装类组。

五、使用AGG的软件
       我前段时间上网查2D图形功能,结果发现了许多库都是或多或少地使用了AGG,于是才对AGG感兴趣,我看中了它的跨平台性,以及运行速度和内存占用等。现在提供几个在内部使用AGG的比较有名的开源项目:
Inkspace:一个跨平台的SVG编辑软件,部分使用了AGG的功能(还使用了ArtLib的功能,我以后会对ArtLib作介绍)。
wxArt2d:一个基于Wxwindow的2D图形编辑软件,提供了AGG可以一种作图选择。
vcf:一个C++框架库,使用AGG作为图形输出。
这些库都可以到
http://www.sf.net/上找到。

一、 概要
     AGG是一个用标准的平台无关的C++写成的通用图形工具包。它可以应用在计算机程序中需要高质量的2D图形的许多方面。例如,AGG可以用于渲染2D地图。AGG只使用了C++和标准C的函数,如memcpy,sin,cos,sqrt等。基本的算法甚至没有使用C++ Standard Template Library。因此,AGG能够在大量的应用软件中使用,包括嵌入式系统中。
     另一方面,AGG允许对库的一部分进行替换,比如在它不能适应性能的要求时。如果需要,你也能够添加其他的颜色空间。因为AGG是基于C++的模板机制的。
     AGG不是一个紧密的图形库,它并不容易使用。这是由于考虑到AGG是一个“创建其他工具的工具”。这意味着,没有“Graphcis”对象或是其他类似的东西。取而代之的是许多组织松散的、能单独或是组合使用的算法。这些算法有着定义良好的接口,它们之间有着尽可能最小的隐式或显式的依赖关系。
1. 建议
     AGG最主要的目标是打破一下旧的传统(针对GDI,GDI++的一些缺点,比如过于庞大,不能修改以满足要求等)。AGG所要展示的是稳定,轻巧,灵活和自由。与STL不同,AGG是C++图形库。STL通常能够很方便的直接在程序中使用。而并不建议象使用STL那样使用AGG。更好的使用AGG的方法是,可以针对需要处理的问题对它进行简单的封装后进行使用。这与GDI+有什么不同?首先,可以对封装后的AGG完全进行控制。AGG只是提供了一系列基本的算法,而这些算法间有着很少的的关联。可以只定义接口,转换管道和输出的形式。甚至可以替代任何已经存在的图形接口的一部分。例如,可以使用AGG的光栅化器来在屏幕上显式图形并直接调用用GDI来打印。下图是GDI+和AGG的渲染品质的比较。
GDI+和AGG的渲染品质的比较
     但最重要的是,如果程序设计的足够灵活,这可以使得程序变成完全可移植的。
2. 反锯齿和亚像素精度
     反锯齿是用于在低分辩率设备上显示图象时改善视觉品质的一种广为人知的技术。它基于人类的视觉特性。看看下图,尝试猜测一下是什么意思。
这是一个用反锯齿方式绘制的词
      这是一个用反锯齿方式绘制的词。
 
正常大小的同一幅图现在来看看正常大小的同一幅图。能够很容易的分辨出这是“stereo”。然而这是两幅相同的图。只是第一幅比第二幅大。反锯齿并没有让它看起来更清楚,它只是让你的大脑更容易推断出是什么。
AGG中不仅仅使用了反锯齿,它还利用了亚像素精度的技术。下图中显示了使用简单的Bresenham差值放大后的结果。
subpixel_bresenham

     如图中(2)和(3),由于利用了亚像素精度,虽然线的起始点和结束点是同样的,但是可以表示两种不同的线。而如果不利用亚像素精度,同样的起始点和结束点则只能表示一种线,如(1)。
     如果同时利用亚像素精度和反锯齿,就能够获得更好的效果。
    看看下面的图有什么不同:
      aliased_pix_accuracy    aliased_subpix_accuracy    anti_aliased
     这三个螺旋形可以近似的看成是由短的直线段组成的。左边的那幅图采用的是正常的Integer Bresenham方法(使用Windows GDI的LineTo和MoveTo函数也可以得到类似的效果)。中间的图采用了改进后的精度为1/256像素的Integer Bresenham方法。而右边的图同样使用了1/256像素的精度,但是同时还使用了反锯齿。请注意,将线段中亚像素真实定位的能力非常重要。如果我们对正常像素坐标使用反锯齿,那么螺旋形看起来会更平滑,但仍然同左边的图一样难看。
     亚像素精度甚至比控制线的视觉厚度(visual thickness)更加重要。只有当我们有一个好的反锯齿算法时,良好的精确性才能成为可能。另一方面,如果我们可以只用一个点的离散性来确定线的宽度,那么反锯齿就没有什么用处了。反锯齿和亚像素精确度总是协同使用的。
现代显示器的分辨率最多是120DPI,而利用亚像素精度可以达到300DPI。下面的图片显示的线的宽度从0.3像素开始,依次递增0.3像素。
用反锯齿和亚像素精度渲染的线
                                                            用反锯齿和亚像素精度渲染的线
     下面是两个用亚像素精度进行渲染的例子:
用反锯齿和亚像素精度渲染的圆形
                                                           用反锯齿和亚像素精度渲染的圆形
 
可爱的狮子
                                                                       可爱的狮子
      请注意:那些小的狮子虽然丢失了一些细节,但还是保持了与较大狮子的一致性。
二、 基本观念
1. 库的设计
     AGG被设计成一系列松散的算法和类模板。因此所有的部分都能够很容易的组合起来。基于模板的设计使得可以替代库的一部分而不需要修改一行代码。AGG也被设计的易扩展和灵活。可以在其中很容易的添加新的算法。
     AGG并没有指定任何它的形式,可以自由的使用它的任何一部分。然而,AGG被当作一个在内存中渲染图象的工具。这是学习AGG的一个不错的着手点,可这样并不十分准确。在AGG提供的教程中有如何开始学习AGG更好的例子。
     下面是一个典型的AGG渲染途径。 
典型的AGG渲染途径
     注意在Vertex Source和Screen Output之间的任一步骤都不是强制性的。例如,你能使用基于Windows API光栅化器,这样你就不需要AGG的光栅化和渲染了。如果只想绘制线,可以使用AGG的outline 光栅化器,这样可以更快。
    对上图的一些说明:
 Vertex Source
Vertex Source是一些对象。如多边形,polyline等一系列连续的2D顶点。可以通过MoveTo,LineTo产生。
 Coordinate conversion pipeline
Coordinate conversion pipeline由一组坐标转换器组成。它通常作用于用浮点数描绘的矢量数据(X,Y)。可能会包括一些几何变换,轮廓生成等。
 Scanline Rasterizer
Scanline Rasterizer把矢量数据转换成许多水平的扫描线。这些扫描线通常(不是必须)带有反锯齿的信息。
 Renderers
Renderers对扫描线进行渲染。把渲染的结果写入rendering buffer。
 Rendering Buffer
Rendering Buffer是内存中的一个在后面用于显示的缓冲区。通常(不是必须)它包含了适应于显示系统的像素格式。如,24位的B-G-R,32位的B-G-R-A或15位的R-G-B-555等。
2. 颜色,颜色空间和像素格式    
     在AGG中颜色直到要把数据放入rendering buffer中时才在渲染过程中出现。一般来说,没有通常“color”意图的结构体或类。AGG总是对具体的颜色空间进行操作。这儿包括的颜色空间有很多种,如RGB,HSV,CMYK等。这些颜色空间通常有特定的限制。比如,RGB空间就只是人眼可见颜色的一个很小的子集,下图中的三角形区域。
 
CIE色品图和RGB色域
                                                                CIE 色品图和RGB色域
     换句话说,在真实世界中有很多颜色是不能用RGB,CMYK,HSV等颜色空间来描述的。除了自然中存在的,任何一个其他颜色空间都是受限制的。因此,为了避免在将来可能出现的限制,没有引入一个如“color”般的对象。
3. 坐标单位
     AGG主要使用输出设备的坐标。在屏幕上就是像素。但是不同于其他一些库和API,AGG支持亚像素精度。这意味着需要用浮点数描述坐标,因为小数部分的值也将会产生影响。为了不限制使用者的自由,AGG中没有嵌入从世界坐标转换到屏幕坐标的转换机制。当不同的应用软件中需要不同的近似方式时,这就显得很重要了。AGG只是提供了从view port到设备的变换器。可以添加自己的简单的类来以毫米、英寸或是其他物理单位为单位进行转换。
posted @ 2008-08-19 23:36  Kane_BJ  阅读(12317)  评论(5编辑  收藏  举报