AGG 库是一个跨平台的2D图形库,全称是“Anti-Grain Geometry”。从名字上就能看出它的特色就是有很好的抗锯齿效果,当然GDI+也有抗锯齿功能,不过GDI+不能跨平台不是?而且有人测试说AGG 比GDI+快10倍以上,虽然有吹牛之嫌,不过比GDI+快是没错的了。
C++Builder用的是VCL库,VCL里的绘图类TCanvas最终调用的是GDI API,所以画的曲线有明显的锯齿
对比一下TCanvas画的和AGG画的:
TCanvas作品(GDI) | AGG作品 |
下面是源代码:在名为img1的TImage里画一个三角形
用TCanvas画
- TCanvas *pCanvas = img1->Canvas;
- pCanvas->FillRect( img1->ClientRect );
- pCanvas->MoveTo(21, 34);
- pCanvas->LineTo(398, 123);
- pCanvas->LineTo(165, 302);
- pCanvas->LineTo(21, 34);
用AGG画
- // 生成24位TBitmap给AGG使用
- Graphics::TBitmap *pBmp = new Graphics::TBitmap;
- pBmp->PixelFormat = pf24bit;
- pBmp->Width = img1->Width;
- pBmp->Height = img1->Height;
- // 得到TBitmap的位图数据(点阵缓存,每行字节数等)
- BITMAP bmp;
- ::GetObject(pBmp->Handle, sizeof(bmp), &bmp);
- //============================================================
- // 轮到 AGG 了
- // 把pBmp的点阵缓存包装成AGG认识的rendering_buffer类
- agg::rendering_buffer rbuf(
- (unsigned char*)bmp.bmBits,
- pBmp->Width, pBmp->Height,
- -bmp.bmWidthBytes);
- // Windows的24位BMP是BGR格式,所以用pixfmt_bgr24
- agg::pixfmt_bgr24 pixf(rbuf);
- agg::renderer_base<agg::pixfmt_bgr24> renb(pixf);
- // 以白色填充
- renb.clear(agg::rgba8(255, 255, 255));
- // Rasterizer & scanline
- agg::rasterizer_scanline_aa<> ras;
- agg::scanline_p8 sl;
- // 在ras里画个三角形
- {
- agg::path_storage ps;
- ps.move_to(21,34);
- ps.line_to(398, 123);
- ps.line_to(165, 302);
- ps.close_polygon();
- agg::conv_stroke<agg::path_storage> csps(ps);
- ras.add_path(csps);
- // 把ras里的东东画到renb上,抗锯齿
- agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(80, 90, 60));
- }
- //============================================================
- img1->Picture->Assign(pBmp);
- delete pBmp;
要编译上面AGG的代码,请按以下步骤配置
- 下载AGG库,它的家在http://www.antigrain.com,目前最高版本是AGG2.5
- 解压,后面以[AGG]表示AGG的解压目录.
- 把[AGG]/include加入到C++Builder项目的include目录中
- 把[AGG]/src里所有cpp加入到C++Builder项目中
- 引用AGG头文件,编译,完成
- #include "agg_scanline_p.h"
- #include "agg_renderer_scanline.h"
- #include "agg_pixfmt_rgba.h"
- #include "agg_rasterizer_scanline_aa.h"
- #include "agg_path_storage.h"
- #include "agg_ellipse.h"
- #include "agg_conv_stroke.h"
- #include "agg_conv_transform.h"
- #include "agg_span_allocator.h"
- #include "agg_span_gradient.h"
- #include "agg_span_interpolator_linear.h"
注:如果打算经常用AGG,可以考虑把AGG直接编译成lib,
进入控制台模式 cd [AGG]/src bcc32 -c -b- -O2 -I../include *.cpp for %1 in (*.obj) do tlib agg_bcc.lib +%1 del *.obj
执行上面命令后会生成一个agg_bcc.lib文件,以后只要把它加入项目即可,注意bcc32的(-b-)选项,如果你的项目里 “Treat enum types as ints”是打开的,就把这个-b-选项去掉。
由于AGG是跨平台库,为了保持通用性,它只负责处理内存中的点阵数据,如本例中的bmp.bmBits。并且AGG对图像的载入和保存支持有限(实际上它在Windows下只支持bmp),如果要支持jpg,png,gif之类格式的支持,可以考虑先用其它图像库(如CxImage,甚至GDI+也行)载入图像,然后还原成点阵给AGG处理。
这里不得不再次佩服一下Borland/CodeGear的功力,VCL的TCanvas包装得确实好,相对于AGG来说代码简单得不是一个数量级。如果哪位有兴趣(+有时间、有能力),把AGG包装成与TCanvas相似的接口那绝对是功德无量啊~~
关于AGG更多的细节,请留意http://www.cpp-prog.com/