在C++Builder里使用AGG库

AGG 库是一个跨平台的2D图形库,全称是“Anti-Grain Geometry”。从名字上就能看出它的特色就是有很好的抗锯齿效果,当然GDI+也有抗锯齿功能,不过GDI+不能跨平台不是?而且有人测试说AGG 比GDI+快10倍以上,虽然有吹牛之嫌,不过比GDI+快是没错的了。

C++Builder用的是VCL库,VCL里的绘图类TCanvas最终调用的是GDI API,所以画的曲线有明显的锯齿

对比一下TCanvas画的和AGG画的:

TCanvas作品AGG作品
TCanvas作品(GDI)AGG作品

 

下面是源代码:在名为img1的TImage里画一个三角形

用TCanvas画

 

  1. TCanvas *pCanvas = img1->Canvas;
  2.  
  3. pCanvas->FillRect( img1->ClientRect );
  4. pCanvas->MoveTo(21, 34);
  5. pCanvas->LineTo(398, 123);
  6. pCanvas->LineTo(165, 302);
  7. pCanvas->LineTo(21, 34);

 

用AGG画

 

  1. // 生成24位TBitmap给AGG使用
  2. Graphics::TBitmap *pBmp = new Graphics::TBitmap;
  3. pBmp->PixelFormat = pf24bit;
  4. pBmp->Width = img1->Width;
  5. pBmp->Height = img1->Height;
  6.  
  7. // 得到TBitmap的位图数据(点阵缓存,每行字节数等)
  8. BITMAP bmp;
  9. ::GetObject(pBmp->Handle, sizeof(bmp), &bmp);
  10.  
  11. //============================================================
  12. // 轮到 AGG 了
  13. // 把pBmp的点阵缓存包装成AGG认识的rendering_buffer类
  14. agg::rendering_buffer rbuf(
  15.     (unsigned char*)bmp.bmBits,
  16.     pBmp->Width, pBmp->Height,
  17.     -bmp.bmWidthBytes);
  18.  
  19. // Windows的24位BMP是BGR格式,所以用pixfmt_bgr24
  20. agg::pixfmt_bgr24 pixf(rbuf);
  21. agg::renderer_base<agg::pixfmt_bgr24> renb(pixf);
  22. // 以白色填充
  23. renb.clear(agg::rgba8(255, 255, 255));
  24.  
  25. // Rasterizer & scanline
  26. agg::rasterizer_scanline_aa<> ras;
  27. agg::scanline_p8 sl;
  28.  
  29. // 在ras里画个三角形
  30. {
  31.     agg::path_storage ps;
  32.     ps.move_to(21,34);
  33.     ps.line_to(398, 123);
  34.     ps.line_to(165, 302);
  35.     ps.close_polygon();
  36.  
  37.     agg::conv_stroke<agg::path_storage> csps(ps);
  38.     ras.add_path(csps);
  39.     // 把ras里的东东画到renb上,抗锯齿
  40.     agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(80, 90, 60));
  41. }
  42. //============================================================
  43. img1->Picture->Assign(pBmp);
  44.  
  45. delete pBmp;

 

要编译上面AGG的代码,请按以下步骤配置

  1. 下载AGG库,它的家在http://www.antigrain.com,目前最高版本是AGG2.5
  2. 解压,后面以[AGG]表示AGG的解压目录.
  3. 把[AGG]/include加入到C++Builder项目的include目录中
  4. 把[AGG]/src里所有cpp加入到C++Builder项目中
  5. 引用AGG头文件,编译,完成
    1. #include "agg_scanline_p.h"
    2. #include "agg_renderer_scanline.h"
    3. #include "agg_pixfmt_rgba.h"
    4. #include "agg_rasterizer_scanline_aa.h"
    5. #include "agg_path_storage.h"
    6. #include "agg_ellipse.h"
    7. #include "agg_conv_stroke.h"
    8. #include "agg_conv_transform.h"
    9. #include "agg_span_allocator.h"
    10. #include "agg_span_gradient.h"
    11. #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/

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值