(轉)用AGG實作高品質圖形輸出(一)
2011-04-27 09:38
CoolJie
閱讀(1943)
評論(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的工作原理,先看一段代碼:
#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 renderer_base_type;
renderer_base_type renb(pixf);
typedef agg::renderer_scanline_aa_solid renderer_scanline_type;
renderer_scanline_type rensl(renb);
// Vertex Source
agg::ellipse ell(100,100,50,50);
// Coordinate conversion pipeline
typedef agg::conv_contour ell_cc_type;
ell_cc_type ccell(ell);
typedef agg::conv_stroke 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;
}
編譯這段代碼的方法是(以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工作流程。
轉自:http://www.cppprog.com/2009/0816/146.html