(转)用AGG实现高质量图形输出(一)
2011-04-27 09:38 CoolJie 阅读(2324) 评论(3) 编辑 收藏 举报AGG是一个开源、高效的跨平台2D图形库。AGG的功能与GDI+的功能非常类似,但提供了比GDI+更灵活的编程接口,其产生的图形的质量也非常高(自称超过GDI+)
使用前AGG的准备工作
- 下载AGG库,它的家在http://www.antigrain.com,目前最高版本是AGG2.5
- 解压,后面以[AGG]表示AGG的解压目录.
- 把[AGG]\include加入到include搜索目录中
- 把[AGG]\src里所有cpp加入到项目中(或者用makefile一起编译)
- 另外,AGG还有一些其它组件,用到时也要把它们(都是些.h和.cpp文件)加入项目:
- 如果要用AGG的控件和窗体,要加入[AGG]\src\ctrl\*.cpp和[AGG]\src\platform\<OS>\*.cpp,头文件在[AGG]\include\ctrl和[AGG]\include\platform里
- 如果要用到TrueType字体显示,要加入[AGG]\font_win32_tt目录下的源码和头文件。利用freetype库,则是[AGG]\font_freetype目录。
- 如果要用到Generic Polygon Clipper库(一个区域剪裁计算库),加入[AGG]\gpc目录下的源码和头文件。
AGG图形显示原理见下图:
其中:
- Vertex Source 顶点源,里面存放了一堆2D顶点以及对应的命令,如"MoveTo"、"LineTo"等。
- Coordinate conversion pipeline 坐标转换管道,它可以变换Vertex Source中的顶点,比如矩阵变换,轮廓提取,转换为虚线等。
- Scanline Rasterizer 把顶点数据(矢量数据)转换成一组水平扫描线,扫描线由一组线段(Span)组成,线段(Span)包含了起始位置、长度和覆盖率(可以理解为透明度)信息。AGG的抗锯齿(Anti-Aliasing)功能也是在这时引入的。
- Renderers 渲染器,渲染扫描线(Scanline)中的线段(Span),最简单的就是为Span提供单一颜色,复杂的有多种颜色(如渐变)、使用图像数据、Pattern等。
- Rendering Buffer 用于存放像素点阵数据的内存块,这里是最终形成的图像数据。
要理解AGG的工作原理,先看一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include "agg_basics.h" #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_scanline_u.h" #include "agg_renderer_scanline.h" #include "agg_pixfmt_rgb.h" #include "platform/agg_platform_support.h" #include "agg_ellipse.h" #include "agg_conv_contour.h" #include "agg_conv_stroke.h" class the_application : public agg::platform_support { public : the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y) { } virtual void on_draw() { //Rendering Buffer agg::rendering_buffer &rbuf = rbuf_window(); agg::pixfmt_bgr24 pixf(rbuf); // Renderers typedef agg::renderer_base<agg:agg:agg:agg:agg:agg:agg:agg::pixfmt_bgr24> renderer_base_type; renderer_base_type renb(pixf); typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type; renderer_scanline_type rensl(renb); // Vertex Source agg::ellipse ell(100,100,50,50); // Coordinate conversion pipeline typedef agg::conv_contour<agg:agg:agg:agg:agg:agg:agg:agg::ellipse> ell_cc_type; ell_cc_type ccell(ell); typedef agg::conv_stroke<ell_cc_type> ell_cc_cs_type; ell_cc_cs_type csccell(ccell); // Scanline Rasterizer agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; // Draw renb.clear(agg::rgba8(255,255,255)); for ( int i=0; i<5; i++) { ccell.width(i*20); ras.add_path(csccell); rensl.color( agg::rgba8(0,0,i*50)); agg::render_scanlines(ras,sl,rensl); } } }; int agg_main( int argc, char * argv[]) { the_application app(agg::pix_format_bgr24, false ); app.caption( "AGG Example. Anti-Aliasing Demo" ); if (app.init(600, 400, agg::window_resize)) { return app.run(); } return -1; }</ell_cc_type></agg:agg:agg:agg:agg:agg:agg:agg::ellipse></renderer_base_type></agg:agg:agg:agg:agg:agg:agg:agg::pixfmt_bgr24> |
编译这段代码的方法是(以VC为例):
- 新建空白GUI项目(就是有WinMain的项目)
- 把[AGG]\src里所有*.cpp加入到项目中
- 把[AGG]\src\platform\Win32\*.cpp加入到项目中
- Ctrl+C/Ctrl+V 上面的代码
- 编译!
显示效果:
我们先不管agg_main及agg::platform_support的问题,实际上agg::platform_support只是AGG给我们方便显示AGG图形用的,真正应用时几乎不会用到(后面会讲到怎样把AGG图形画到HDC上)。
现在我们只需要知道这个框架可以生成一个窗体,当窗体重画时会调用virtual void on_draw()就行了。
现在直接从on_draw()开始看
- 通过rbuf_window()方法得到一个agg::rendering_buffer,它就是“Rendering Buffer”,是一块用于存放图像的内存块。通过pixfmt_bgr24包装,我们就可以以像素为单位存取图像。
- agg::renderer_base和agg::renderer_scanline_aa_solid都属于"渲染器Renderer"。renderer_base为底层渲染器,它支撑起所有的高层渲染器。这里的renderer_scanline_aa_solid就是一个高层渲染器。
- agg::ellipse是“顶点源Vertex Source”,这个顶点源呈现的是一个圆形。
- agg::conv_contour和agg::conv_stroke作为“坐标转换管道Coordinate conversion pipeline”,conv_contour扩展轮廓线,conv_stroke只显示轮廓线(如果没有conv_stroke就会显示实心圆,可以去掉试试)。
- agg::rasterizer_scanline_aa<>就是“Scanline Rasterizer”啦。
- agg::render_scanlines函数执行这个AGG工作流程。
Pop Jungle是我的新作,希望大家喜欢
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!