AGG高质量图形输出 下载本文

内容发布更新时间 : 2024/4/28 21:25:54星期一 下面是文章的全部内容请认真阅读。

x, int y, int len,

const color_type* colors, const cover_type* covers);

void copy_from(const rendering_buffer& from,

const rect* rc=0, int x_to=0, int y_to=0); 实验代码(基于此 处代码)

在on_draw()方法的renb.clear(agg::rgba8(255,255,255));语句后面加上: ? renb.clear(agg::rgba8(255,255,255));

? renb.clip_box(30,30,160,160); // 设置可写区域

得到的图形是:

从from复制一个矩形区域过来,rc指定源区域,x_to,y_to指定目标位置

PixelFormat Renderer

PixelFormat Renderer的作用是以指定的颜色空间来包装原始的Rendering Buffer(见后文),AGG把它归类于底层Renderer。

Rendering Buffer是以字节为单位的,而PixelFormat Renderer则是以像素为单位的。 头文件

#include \#include \ 类型

pixfmt_gray8 pixfmt_rgb24 pixfmt_bgr24 pixfmt_rgba32

pixfmt_bgr24_gamma ... 构造函数

pixfmt_base(rbuf_type& rb);

rb参数为Rendering Buffer类型 类型定义

像素类型

typedef color_type;

需要了解的是在AGG中像素也是一个功能完善的类,常用的有rgba、rgba8、gray8。

rgba里每个颜色分量用double表示,范围从0~1。其它像素类后面的数字代表每个颜色分量占用的位数。大部分像素类都可以从rgba构造。 同时, 像素类还有gradient等牛X的颜色计算方法。

typedef value_type; typedef order_type; 成员方法 unsigned width() unsigned height()

宽高

单个颜色分量的类型

颜色排序方式,我们可以通过里面的枚举值R G B A得到各颜色分量所在位置,常用的有order_rgb,order_bgr,order_rgba。

这是order_rgb的定义: struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; };

color_type pixel(int x, int y);

void copy_pixel(int x, int y, const 取得、设置指定点的颜色

color_type& c);

与原颜色有混合效果,强度由covervoid blend_pixel(int x, int y, const 设置指定点颜色,

指定 color_type& c, int8u cover);

void copy_hline(int x, int y, unsigned

从x,y开始画一条长度为len的线,颜色为c,同样len, const color_type& c);

void copy_vline(int x, int y, unsigned 有blend_版本 len, const color_type& c);

void blend_solid_h(v)span(int x, int y, unsigned len,

const

类似hline和vline版本,color版指定一组颜色,依

color_type& c, const int8u* covers);

次着色。covers指定覆盖率

void blend_color_h(v)span(int x, int y, unsigned len,

const

color_type* colors, const int8u* covers); 实验代码(基于此 处代码)

在on_draw()方法的最后加上:

? //从50,20开始,画20条长度为100的坚线,颜色从黑渐变到红,覆盖率为128(半透明) ? for(int i=0; i<20; i++)

? pixf.blend_vline(50+i,20,100,agg::rgba(i/20.0,0,0),128);

得到的图形是:

Rendering Buffer

Rendering Buffer是一个内存块,用于保存图像数据。这是AGG与显示器之间的桥梁,我们要显示AGG图形实际上就是识别这个内存块并使用系统的API显示出来 而已(实际上几乎不需要做转换工作,因为无论是Windows还是Linux,API所用的图像存储格式与Rendering Buffer都是兼容的)。 头文件:

#include \ 类型: rendering_buffer 构造函数:

rendering_buffer(int8u* buf, unsigned width, unsigned height, int stride);

参数分别表示内存块指针,宽、高、每行的步幅(当步幅<0时,表示上下颠倒) 成员方法:

void attach(int8u* buf, unsigned width, unsigned height, int stride);

int8u* buf();

unsigned width() const; unsigned height() const; int stride() const;

unsigned stride_abs() const; int8u* row_ptr(int y) void clear(int8u value)

template void copy_from(const RenBuf& src)

实验代码(基于此处代码)

在on_draw()方法的最后加上:

? agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针 ? memset(p,0,rbuf.stride_abs());//整行以0填充

得到的图形是:

参数与构造函数相同 返回内存块指针

返回宽、高、每行步幅

返回指向第y行起点的指针 以value值填充整个内存块

从另一rendering_buffer中复制数据

AGG与GDI显示

Rendering Buffer的图像存储方式和Windows的BMP是一样的,所以让AGG处理BMP是很简单的事情,下面的代码演示了怎样在HDC上显示AGG

? #include ? ? ? ?

#include #include

#include #include

? ...

? // 首先让系统生成一个32位的bmp缓存 ?? ?? ?? ??

BITMAPINFO bmp_info;

bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmp_info.bmiHeader.biWidth = width; bmp_info.bmiHeader.biHeight = height;

?? bmp_info.bmiHeader.biPlanes = 1; ?? bmp_info.bmiHeader.biBitCount = 32;

?? bmp_info.bmiHeader.biCompression = BI_RGB; ?? bmp_info.bmiHeader.biSizeImage = 0; ?? bmp_info.bmiHeader.biXPelsPerMeter = 0; ?? bmp_info.bmiHeader.biYPelsPerMeter = 0; ?? bmp_info.bmiHeader.biClrUsed = 0; ?? bmp_info.bmiHeader.biClrImportant = 0; ??

?? HDC mem_dc = ::CreateCompatibleDC(hdc); ??

?? void* buf = 0; ??

?? HBITMAP bmp = ::CreateDIBSection( ?? mem_dc, ?? &bmp_info, ?? ?? ?? ??

DIB_RGB_COLORS, &buf, 0, 0

?? ); ??

?? // 把bmp与mem_dc关联,这样AGG就可以和原生GDI一起工作了 ?? HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); ??

?? //============================================================ ?? // 以下是AGG代码

?? agg::rendering_buffer rbuf;

?? // 32位位图,每行字节数为width*4。

?? // BMP是上下倒置的,为了和GDI习惯相同,最后一个参数是负值。 ?? rbuf.attach((unsigned char*)buf, width, height, -width*4); ??

?? // 像素格式和renderer_base ?? agg::pixfmt_bgra32 pixf(rbuf);

?? agg::renderer_base renb(pixf); ??

?? renb.clear(agg::rgba8(255, 255, 255, 255)); ??

?? // Scanline renderer