(转)用AGG实现高质量图形输出(一)
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工作流程。
(转)用AGG实现高质量图形输出(一)的更多相关文章
- (转)用AGG实现高质量图形输出(二)
本文上接<用AGG实现高质量图形输出(一)>,分别介绍了AGG显示流程中的各个环节. 上次讲了AGG的显示原理并举了一个简单的例子,这一篇文章开始讲AGG工作流程里的每个环节.为了方便对照 ...
- (转)用AGG实现高质量图形输出(三)
转自 :http://www.cnblogs.com/CoolJie/archive/2011/04/27/2030260.html 线段生成器(Span Generator) 我们前面举的例子使用的 ...
- (转)用AGG实现高质量图形输出(四)
AGG的字符输出 字符输出,对于AGG来说,这个功能可以处于显示流程的 不同位置.比如字体引擎可直接处于“Scanline Rasterizer”层向渲染器提供已处理完毕的扫描线,也可以处于“Vert ...
- matplotlib简介-高质量图形输出
Matplotlib 是一个用来绘制二维图形的 Python 模块,它克隆了许多 Matlab 中的函数, 用以帮助 Python 用户轻松获得高质量(达到出版水平)的二维图形. 文章来源:http: ...
- R语言绘图高质量输出
R语言通过支持Cairo矢量图形处理的类库,可以创建高质量的矢量图形(PDF,PostScript,SVG) 和 位图(PNG,JPEG, TIFF),同时支持在后台程序中高质量渲染.在ggplot2 ...
- 编写高质量代码改善C#程序的157个建议——建议13: 为类型输出格式化字符串
建议13: 为类型输出格式化字符串 有两种方法可以为类型提供格式化的字符串输出.一种是意识到类型会产生格式化字符串输出,于是让类型继承接口IFormattable.这对类型来 说,是一种主动实现的方式 ...
- 高质量C++/C编程指南(林锐)
推荐-高质量C++/C编程指南(林锐) 版本/状态 作者 参与者 起止日期 备注 V 0.9 草稿文件 林锐 2001-7-1至 2001-7-18 林锐起草 V 1.0 正式文件 林锐 20 ...
- 高质量C++[转]
高质量C++/C编程指南 文件状态 [ ] 草稿文件 [√] 正式文件 [ ] 更改正式文件 文件标识: 当前版本: 1.0 作 者: 林锐 博士 完成日期: 2001年7月24日 版 本 ...
- R语言的高质量图形渲染库Cairo(转)
前言 R语言不仅在统计分析,数据挖掘领域,计算能力强大.在数据可视化上,也不逊于昂贵的商业.当然,背后离不开各种开源软件包的支持,Cairo就是这样一个用于矢量图形处理的类库. Cairo可以创建高质 ...
随机推荐
- Oracle锁表(转载)
锁定类型 行级锁 表级锁行级锁 ---- 行被排他锁定 ----在某行的锁被释放之前,其他用户不能修改此行 ...
- (转载)OC学习篇之---Foundation框架中的NSArray类和NSMutableArray类
在之前的一篇文章中介绍了Foundation框架中的NSString类和NSMutableString类,今天我们继续来看一下Foundation框架中的NSArray类和NSMutableArray ...
- php连接数据库
<?php header('Content-Type:text/html; charset=utf-8'); define('DB_HOST', 'localhost'); define('DB ...
- QCon2013上海站总结 -- 前端开发
选择这个专题开始主要有两个原因:一是这次会议关于前端开发的内容不多.二是我做过几年前端开发,这个专题对我来说会容易点:) 这次QCon上海关于前端开发有一个Keynote,一个Javascript专题 ...
- something: 重构、正则、vim -- clwu
项目需要做一个db table 操作的小工具. 从phpMyAdmin上拷贝了一些代码过来修改,但我有没有足够的时间把所有拷贝过来的代码都重构修改和测试完,于是希望后面接手的同事在需要修改这些代码时能 ...
- Arduino1.7.10在Ubuntu下创建快捷方式
从官网下载的arduino1.7.10版本没有快捷方式只有可执行文件arduino,通过下面的方法可以创建快捷方式 打开链接:http://www.easyicon.net/1171938-ardui ...
- 解决SQL Server Always 日志增大的问题-摘自网络
配置了Alwayson之后,因为没有只能使用完全恢复模式,不能使用简单或大容量日志模式,所以日志不断增长,不能使用改变恢复模式的方式清空日志 手动操作收缩或截断日志也无效 读了一些文章后发现,有人使用 ...
- js_sl 无缝切换
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Linux下的grep搜索命令详解(一)
Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达 ...
- POJ 1160Post Office
POJ 1160 Post Office 我不知道优化,我只知道最暴力的方法,O(V^3),居然100ms不到的过了 设DP[i][j][k]表示考虑前i个小镇,放了j个邮局,最后一个邮局的所在 ...