(转)用AGG实现高质量图形输出(三)
转自 :http://www.cnblogs.com/CoolJie/archive/2011/04/27/2030260.html
线段生成器(Span Generator)
我们前面举的例子使用的都是简单的单一实色,如蓝色的圆、黑色的线等。这是因为在例子里我们一直使用renderer_scanline_aa_solid或render_scanlines_aa_solid。
在上篇文章的渲染器一节中除了renderer_scanline_aa_solid外,还提到有一个renderer_scanline_aa,这里再写一遍它的声明:
1
2
|
template < class BaseRenderer, class SpanAllocator, class SpanGenerator> class renderer_scanline_aa; |
另外,还有一个函数版本:
1
2
3
|
template < class spanallocator, spangenerator baserenderer, scanline, rasterizer,> void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, SpanAllocator& alloc, SpanGenerator& span_gen); |
renderer_scanline_aa (还有一个兄弟版本renderer_scanline_bin)可以按指定的图案或不同的颜色(如渐变)填充顶点源里的多边形。其中的模板参数 SpanAllocator用于准备span,我们直接使用agg::span_allocator就行。这里的SpanGenerator就是本节要说 的线段生成器,它决定了最终用什么东西填到rendering_buffer里。
线段生成器品种很多,常用的在致可以分成图案类和色彩类两大部分:图案类线段生成器使用已有图像作为span来源;色彩类线段生成器使用指定的颜色作为span来源。
图案类线段生成器
头文件
1
2
3
4
5
6
|
#include <agg_span_image_filter_gray.h> #include <agg_span_image_filter_rgb.h> #include <agg_span_image_filter_rgba.h> #include <agg_span_pattern_gray.h> #include <agg_span_pattern_rgb.h> #include <agg_span_pattern_rgba.h> |
类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
template < class source, interpolator&> span_image_filter_[gray|rgb|rgba] template < class source, interpolator> span_image_filter_[gray|rgb|rgba]_2x2 template < class source, interpolator> span_image_filter_[gray|rgb|rgba]_bilinear template < class source, interpolator> span_image_filter_[gray|rgb|rgba]_bilinear_clip template < class source, interpolator> span_image_filter_[gray|rgb|rgba]_nn template < class source, interpolator> span_image_resample_[gray|rgb|rgba] template < class source> span_image_resample_[gray|rgb|rgba]_affine template < class source> class agg::span_pattern_[gray|rgb|rgba] |
上面这些线段生成器类的模板参数都比较相似:Source用于指定图像来源,可以是PixelFormat renderer或agg::image_accessor_clip(由不同的线段生成器类决定);Interpolator是一种插值器,用于填充图 像间隙。我们先写一段示例代码,先看一下线段生成器的作用,也为后面的各种实验做准备。
示例代码,使用span_image_filter_rgb_bilinear_clip
还是基于这个代码(http://www.cppprog.com/2009/0816/146.html),加入下面的头文件
1
2
3
|
#include "platform agg_win32_bmp.h win32" #include "agg_span_allocator.h" #include "agg_span_image_filter_rgb.h" |
在on_draw()方法的最后加上下面这些代码
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
|
... // 以图像填充 agg::pixel_map pm_img; if (pm_img.load_from_bmp( "d:\\spheres.bmp" )) { // pm_img里的图案作为填充来源 agg::rendering_buffer rbuf_img( pm_img.buf(), pm_img.width(), pm_img.height(), -pm_img.stride()); agg::pixfmt_bgr24 pixf_img(rbuf_img); // 我用的bmp是24位的 // 线段分配器 typedef agg::span_allocator<!--?xml: namespace prefix = agg /--><agg::rgba8> span_allocator_type; //分配器类型 span_allocator_type span_alloc; // span_allocator // 插值器 typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 agg::trans_affine img_mtx; // 变换矩阵 interpolator_type ip(img_mtx); // 插值器 // 线段生成器 typedef agg::span_image_filter_rgb_bilinear_clip<agg::pixfmt_bgr24 interpolator_type= "" ,= "" > span_gen_type; // 这个就是Span Generator span_gen_type span_gen(pixf_img, agg::rgba(0,1,0), ip); // 组合成渲染器 agg::renderer_scanline_aa< renderer_base_type, span_allocator_type, span_gen_type > my_renderer(renb, span_alloc, span_gen); // 插值器的矩阵变换 img_mtx.scale(0.5); img_mtx.translate(40,40); img_mtx.invert(); //注意这里 // 用我们的渲染器画圆 ras.add_path(ell); agg::render_scanlines(ras,sl,my_renderer); }</agg::pixfmt_bgr24></agg::rgba8> |
其中的d:\\spheres.bmp是我预先放在D盘里的24位bmp图像,作为填充的来源。
显示效果:
- 在第19行的span_gen_type之前,所有的事情都在为定义这个线段生成器做准备。
- 首先是用pixel_map读取bmp文件,然后生成rendering_buffer和pixfmt_bgr24作为这个线段生成器的"Source"。
- 然后是线段分配器,这个没什么特殊要求的话用span_allocator就可以了。
- 接着是插值器类型,插值器也有几个类型(后面会介绍),它的构造函数需要一个变换矩阵对象,于是我们得为它装备一个。
- 现在,终于可以组合成一个我们的线段生成器了。这里使用的是span_image_filter_rgb_bilinear_clip,它的Source是PixelFormat Renderer,如本例的pixfmt_bgr24。
- span_image_filter_rgb_bilinear_clip的构造函数有三个参数,分别是Source对象,填充来源范围之外的颜色和插值器对象。
- 我 们可以改变插值器的矩阵来变换填充图像,象这里的img_mtx.scale(0.5)和img_mtx.translate(40,40)。要注意的 是,插值器的矩阵运算是从目标位置向源位置计算的(即根据目标位置变换得到对应的填充源位置),所以想对源图像变换的话,要记得最后调用矩阵的 invert()方法取反。
- 最后,画圆。由于ell是ellipse对象,没有被conv_stroke转换的ellipse对象是实心的(多边形而不是多义线),于是填充之。
插值器Interpolator
插值器的作用是连接目标位置和源位置,比如要填充一个8*8的图形,对应的填充源是一个4*4的图像,一种简单的线性插值器就要根据目标的位置线性计算得到源对应的位置,如目标点(4,4)、(4,5)、(5,4)、(5,5)这几个位置点对应到源的(2,2)点上。
头文件
1
2
3
|
#include <agg_span_interpolator_linear.h> #include <agg_span_interpolator_persp.h> #include <agg_span_interpolator_trans.h> |
类型
1
2
3
4
5
6
7
8
9
10
|
template < class Transformer = trans_affine, unsigned SubpixelShift = 8> class agg::span_interpolator_linear template < class Transformer = trans_affine, unsigned SubpixelShift = 8> class agg::span_interpolator_linear_subdiv template <unsigned SubpixelShift = 8> class agg::span_interpolator_persp_exact template <unsigned SubpixelShift = 8> class agg::span_interpolator_persp_lerp template < class Transformer, unsigned SubpixelShift = 8> class agg::span_interpolator_trans |
不同的插值器对于不同的变换有各自的优势,对于大部分应用来说,span_interpolator_linear是比较简单高效的。
实验代码,使用span_interpolator_persp_lerp
把上面的演示代码里的interpolator_type改成span_interpolator_persp_lerp,这是一个透视变换的插值器,输入为源四个角的坐标和目标的四个角上的坐标。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
... // 插值器 //typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 //agg::trans_affine img_mtx; // 变换矩阵不需要了 //interpolator_type ip(img_mtx); // 插值器 typedef agg::span_interpolator_persp_lerp<> interpolator_type; //插值器类型 const double offset = 50; // 偏移 const double scale = 0.5; // 缩放倍数 double src[8]={offset+0,offset+0, offset+pm_img.width()*scale,offset+0, offset+pm_img.width()*scale,offset+pm_img.height()*scale, offset+0,offset+pm_img.height()*scale }; //源四角坐标,按偏移和缩放倍数改变一哈 double dst[8]={0,0, pm_img.width(),0, pm_img.width()+100,pm_img.height(), 100,pm_img.height()-100 }; //目标四角坐标,左右乱扯一哈 interpolator_type ip(src,dst); ... |
最后别忘了把img_mtx相关代码注释掉:
1
2
3
|
//img_mtx.scale(0.5); //img_mtx.translate(40,40); //img_mtx.invert(); //注意这里 |
显示效果:
变换器Transformer
注意一下我们前面用的span_interpolator_linear,以及曾经使用过的conv_transform,默认的模板参数Transformer为trans_affine。我们已经知道trans_affine是一个2*3的变换矩阵。在AGG中,变换器不仅仅只有矩阵,这里将要介绍的就是其它的一些变换器。
头文件
1
2
3
4
5
6
7
|
#include <agg_trans_affine.h> #include <agg_trans_bilinear.h> #include <agg_trans_single_path.h> #include <agg_trans_double_path.h> #include <agg_trans_perspective.h> #include <agg_trans_viewport.h> #include <agg_trans_warp_magnifier.h> |
类型
1
2
3
4
5
6
7
|
agg::trans_affine agg::trans_bilinear agg::trans_single_path agg::trans_double_path agg::trans_perspective agg::trans_viewport agg::trans_warp_magnifier |
实验代码,使用trans_warp_magnifier
同样把示例代码中的插值器部分改成下列代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
... // 插值器 //typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 //agg::trans_affine img_mtx; // 变换矩阵 //interpolator_type ip(img_mtx); // 插值器 typedef agg::span_interpolator_trans< agg::trans_warp_magnifier // 使用trans_warp_magnifier > interpolator_type; //插值器类型 agg::trans_warp_magnifier mag; interpolator_type ip(mag); mag.magnification(0.5); mag.center(100,100); mag.radius(50); ... |
建议把后面的ras.add_path(ell)改成ras.add_path(ccell),画得大一点好看清效果,呵呵
显示效果
图像访问器Image Accessor
也 许有不少同学看到开头的线段生成器一节时,已经尝试修改示例代码中的span_image_filter_rgb_bilinear_clip了(比如改 成span_image_filter_rgb_bilinear)。不过编译时会出错,这是因为大部分的线段生成器类接受的Source模板不是 PixelFormat Renderer,而是Image Accessor即图像存取器。
头文件
1
|
#include <agg_image_accessors.h> |
类型
1
2
3
4
5
6
7
8
|
template < class PixFmt> class agg::image_accessor_clip // 图像以外的地方用指定颜色填充 template < class PixFmt> class agg::image_accessor_clone // 图像以外的地方以图像边缘填充 template < class PixFmt> class agg::image_accessor_no_clip // 图像以外不可读取,否则引发异常 template < class PixFmt, class WrapX, class WrapY> class agg::image_accessor_wrap // 平铺图像,平铺方式由WrapX和WrapY指定 |
实验代码
把示例代码中的span_image_filter_rgb_bilinear_clip部分改成下面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
... // 线段生成器 //typedef agg::span_image_filter_rgb_bilinear_clip<agg::pixfmt_bgr24 interpolator_type="" ,=""> span_gen_type; // 这个就是Span Generator //span_gen_type span_gen(pixf_img, agg::rgba(0,1,0), ip); // 图像访问器 typedef agg::image_accessor_clone<agg::pixfmt_bgr24> image_accessor_type; image_accessor_type accessor(pixf_img); // 使用span_image_filter_rgb_bilinear typedef agg::span_image_filter_rgb_bilinear< image_accessor_type, interpolator_type > span_gen_type; span_gen_type span_gen(accessor, ip); ...</agg::pixfmt_bgr24></agg::pixfmt_bgr24> |
建议把后面的ras.add_path(ell)改成ras.add_path(ccell)
显示效果
image_accessor_wrap类要指定WrapX和WrapY,可选的有:
1
2
3
4
5
6
|
wrap_mode_reflect wrap_mode_reflect_auto_pow2 wrap_mode_pow2 wrap_mode_repeat wrap_mode_repeat_auto_pow2 wrap_mode_repeat_pow2 |
比如我们把本例中的image_accessor_type定义改成
1
2
3
|
//typedef agg::image_accessor_clone>agg::pixfmt_bgr24> image_accessor_type; typedef agg::image_accessor_wrap>agg::pixfmt_bgr24, agg::wrap_mode_reflect,agg::wrap_mode_repeat> image_accessor_type; |
显示效果是
(为了突出效果,用矩阵img_mtx把源缩小了)
图像过滤器(Image Filter)
在 一些线段生成器里,比如 span_image_filter_[gray|rgb|rgba],span_image_resample_[gray|rgb|rgba]等类, 它们的构造函数还有一个“const image_filter_lut &filter”参数,这个参数用于变换图像的像素值。它们的名称都以image_filter作为前缀,AGG中称为Image Filter(图像过滤器)。
头文件
1
|
#include <agg_image_filters.h> |
类型
1
2
3
4
5
6
7
8
|
image_filter_bilinear; image_filter_blackman; image_filter_blackman[36|64|100|144|196|256]; image_filter_kaiser; image_filter_lanczos; image_filter_lanczos[36|64|100|144|196|256]; image_filter_mitchell; ...还有很多呢... |
实验代码
把上面的span_image_filter_rgb_bilinear改成span_image_resample_rgb_affine
1
2
3
4
5
6
7
8
9
10
11
12
13
|
... //typedef agg::image_accessor_clone<agg::pixfmt_bgr24> image_accessor_type; typedef agg::image_accessor_wrap<agg::pixfmt_bgr24, agg::wrap_mode_reflect,agg::wrap_mode_repeat> image_accessor_type; image_accessor_type accessor(pixf_img); //typedef agg::span_image_filter_rgb_bilinear< // image_accessor_type, // interpolator_type > span_gen_type; //span_gen_type span_gen(accessor, ip); typedef agg::span_image_resample_rgb_affine<image_accessor_type> span_gen_type; span_gen_type span_gen(accessor, ip, agg::image_filter_sinc36()); ... |
显示效果
色彩类线段生成器
头文件
1
2
3
4
5
|
#include <agg_span_solid.h> #include <agg_span_gradient.h> #include <agg_span_gradient_alpha.h> #include <agg_span_gouraud_gray.h> #include <agg_span_gouraud_rgba.h> |
类型
1
2
3
4
5
6
7
8
|
template < class ColorT> class agg::span_solid; template < class ColorT, class Interpolator, class GradientF, class ColorF> class agg::span_gradient; template < class ColorT, class Interpolator, class GradientF, class AlphaF> class agg::span_gradient_alpha; template < class ColorT> class agg::span_gouraud_[gray|rgba]; |
如果你是从上面的图案类线段生成器看到这里的话,那么色彩类的就相对简单得多了。同样,我们先写一个示例代码,也方便以后做实验。
示例代码
同样基于这个代码(http://www.cppprog.com/2009/0816/146.html),加入下面的头文件
1
2
|
#include "agg_span_allocator.h" #include "agg_span_gradient.h" |
在on_draw()方法的最后加上下面这些代码
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
|
// 色彩类线段生成器demo // 线段分配器 typedef agg::span_allocator<agg::rgba8> span_allocator_type; //分配器类型 span_allocator_type span_alloc; // span_allocator // 插值器 typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 agg::trans_affine img_mtx; // 变换矩阵 interpolator_type ip(img_mtx); // 插值器 // 渐变方式 typedef agg::gradient_radial_focus gradientF_type; gradientF_type grF(1, 0.1, 0.5); // 渐变颜色 typedef agg::gradient_linear_color<agg::rgba8> colorF_type; colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1)); //白色到蓝色 // 线段生成器 typedef agg::span_gradient<agg::rgba8, interpolator_type, gradientF_type, colorF_type> span_gen_type; span_gen_type span_gen(ip,grF,colorF,0,50); // 组合成渲染器 agg::renderer_scanline_aa< renderer_base_type, span_allocator_type, span_gen_type > my_renderer(renb, span_alloc, span_gen); // 矩阵变换 img_mtx.translate(100,100); img_mtx.invert(); //注意这里 // 使用我们的渲染器画圆 ras.add_path(ell); agg::render_scanlines(ras,sl,my_renderer); |
显示效果
- span_gradient 是一个模板类(费话,AGG的大部分类都是),前两个模板参数ColorT和Interpolator一个是颜色类型一个是插值器没什么好说的了。关键是 后面两个:GradientF用于指定渐变的方式,如水平渐变、垂直渐变、圆形渐变等;ColorF指定渐变的颜色。
- 渐变方式选择了agg::gradient_radial_focus,这是一个可指定焦点的圆形渐变方式。
- 渐变色使用agg::gradient_linear_color设置起始颜色和终止颜色。
- span_gradient的构造函数前三个分别是插值器、渐变方式、渐变颜色,后面两个数字表示渐变的起始和终止位置。不同的渐变方式起始和终止位置的意义是不同的,如在圆形填充里起始和终止表示中心和边缘;水平渐变则表示从左到右。
- 插值器的矩阵变换把这个渐变中心移到(100,100)点上,同样要记得调用invert()方法反转。
渐变颜色
前面说到span_gradient的模板参数ColorF指定渐变的颜色,我们使用的是gradient_linear_color,那么有哪些类可以作为ColorF呢?
AGG文档里说只要实现了“operator []()”和“size()”的类就可以作为ColorF,嗯,std::vector<rgba8>也行哈。
实验代码,使用std::vector<rgba8>实现多颜色渐变
把示例代码的渐变颜色部分改成这样:
1
2
3
4
5
6
7
8
9
10
11
|
... // 渐变颜色 //typedef agg::gradient_linear_color<agg::rgba8> colorF_type; //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色 typedef std::vector<agg::rgba8> colorF_type; colorF_type colorF(256); agg::rgba begin_color(1,1,1), mid_color(1,0,0), end_color(0,0,1); for ( int i=0; i<128; i++) //前128从白到红 colorF[i] = begin_color.gradient(mid_color,i/128.0); for ( int i=0; i<128; i++) //后128从红到蓝 colorF[i+128] = mid_color.gradient(end_color,i/128.0); |
显示效果
这里指定的vector容量256指的是用于的颜色,想要更平滑过渡的话可以使用更多的颜色数。
除了用vector实现多种颜色的渐变外,我们还可以用AGG提供的一个gradient_lut类,用它可以方便很多。
gradient_lut的头文件是#include <agg_gradient_lut.h>
类声明为
1
2
|
template < class ColorInterpolator, unsigned ColorLutSize = 256> class agg::gradient_lut |
其中的ColorInterpolator负责生成两种颜色的中间色,直接使用AGG自带的agg::color_interpolator就行。
通过gradient_lut的add_color(double offset, color_type color)方法添加多种颜色,其中的offset表示添加的颜色所处的偏移位置,取值为0~1之间。
添加完所有颜色后调用build_lut()方法让gradient_lut内部生成颜色数组。
实验代码,使用gradient_lut实现多颜色渐变
把示例代码的渐变颜色部分改成这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
... // 渐变颜色 //typedef agg::gradient_linear_color<agg::rgba8> colorF_type; //colorF_type colorF(agg::rgba(1,1,1), agg::rgba(0,0,1));//白色到蓝色 typedef agg::gradient_lut< agg::color_interpolator<agg::rgba8> > colorF_type; colorF_type colorF; colorF.add_color(0, agg::rgba(1,1,1)); colorF.add_color(0.2, agg::rgba(1,0,0)); colorF.add_color(0.4, agg::rgba(0,1,0)); colorF.add_color(0.8, agg::rgba(0,0,1)); colorF.build_lut(); ... |
显示效果
渐变方式
除本例中的gradient_radial_focus以外,AGG还提供了很多渐变方式,它们都定义在#include <agg_span_gradient.h>头文件之中。
修改演示代码的渐变方式是很简单的,如:
1
2
3
4
5
6
7
|
... // 渐变方式 //typedef agg::gradient_radial_focus gradientF_type; //gradientF_type grF(1, 0.1, 0.5); typedef agg::gradient_x gradientF_type; gradientF_type grF; ... |
这里是其中的一部分AGG自带渐变方式以及显示效果
gradient_x | gradient_y | gradient_diamond |
gradient_xy | gradient_conic | gradient_radial |
本节的最后,再介绍一下其它几个色彩类的线段生成器
- span_solid没什么好说的,实色填充而已
- span_gradient_alpha是透明度渐变,参数和span_gradient差不多,区别是ColorF改成了AlphaF,“operator []()”返回值也由颜色结构变为的透明度数值。
- span_gouraud_rgba 高氏三角着色,需指定三角形的三个顶点和三种颜色,用法见下例
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
|
// 色彩类线段生成器demo // 线段分配器 typedef agg::span_allocator<agg::rgba8> span_allocator_type; //分配器类型 span_allocator_type span_alloc; // span_allocator typedef agg::span_gouraud_rgba<agg::rgba8> span_gen_type; span_gen_type span_gen; //三种颜色 span_gen.colors( agg::rgba(1,0,0), agg::rgba(0,1,0), agg::rgba(0,0,1) ); //三角形三个顶点 span_gen.triangle( 100,50, 130,125, 70,125,0 ); agg::renderer_scanline_aa< renderer_base_type, span_allocator_type, span_gen_type > my_renderer(renb, span_alloc, span_gen); ras.add_path(ell); agg::render_scanlines(ras,sl,my_renderer);</agg::rgba8></agg::rgba8> |
显示效果
组合类线段生成器
头文件
1
|
#include <agg_span_converter.h> |
类型
1
2
|
template < class SpanGenerator, class SpanConverter> class agg::span_converter; |
span_converter的作用是组合两种生成器,比如先由图案类线段生成器产生图案,然后由色彩类线段生成器产生半透明色叠加在图案上。
下面的演示代码演示了怎样组合span_image_filter_rgb_bilinear_clip和span_gradient_alpha两种生成器
演示代码,同样基于这个代码,加入下面的头文件
1
2
3
4
|
#include "agg_span_allocator.h" #include "agg_span_gradient_alpha.h" #include "agg_span_converter.h" #include "span_image_filter_rgb_bilinear_clip.h" |
在on_draw()方法的最后加上下面这些代码
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
|
agg::pixel_map pm_img; if (pm_img.load_from_bmp( "d:\\spheres.bmp" )) { // pm_img里的图案作为填充来源 agg::rendering_buffer rbuf_img( pm_img.buf(), pm_img.width(), pm_img.height(), -pm_img.stride()); agg::pixfmt_bgr24 pixf_img(rbuf_img); // 我用的bmp是24位的 // 线段分配器 typedef agg::span_allocator<agg::rgba8> span_allocator_type; //分配器类型 span_allocator_type span_alloc; // span_allocator // 插值器 typedef agg::span_interpolator_linear<> interpolator_type; //插值器类型 agg::trans_affine img_mtx; // 变换矩阵 interpolator_type ip_img(img_mtx); // 插值器 agg::trans_affine alpha_mtx; // 变换矩阵 interpolator_type ip_alpha(alpha_mtx); // 插值器 // 渐变方式 typedef agg::gradient_x gradientF_type; gradientF_type grF; typedef std::vector<agg::int8u> alphaF_type; alphaF_type alphaF(256); for ( int i=0; i<256; i++) alphaF[i] = i; // Alpha线段生成器 typedef agg::span_gradient_alpha<agg::rgba8 ,= "" alphaf_type= "" gradientf_type,= "" interpolator_type,= "" > alpha_span_gen_type; alpha_span_gen_type alpha_span_gen(ip_alpha,grF,alphaF,0,150); // 图案线段生成器 typedef agg::span_image_filter_rgb_bilinear_clip<agg::pixfmt_bgr24 interpolator_type= "" ,= "" > pic_span_gen_type; pic_span_gen_type pic_span_gen(pixf_img, agg::rgba(0,1,0), ip_img); // 使用span_converter组合成新的线段生成器 typedef agg::span_converter<pic_span_gen_type ,= "" alpha_span_gen_type= "" > span_gen_type; span_gen_type span_gen(pic_span_gen,alpha_span_gen); // 组合成渲染器 agg::renderer_scanline_aa< renderer_base_type, span_allocator_type, span_gen_type > my_renderer(renb, span_alloc, span_gen); // 插值器的矩阵变换 img_mtx.scale(0.5); img_mtx.translate(40,40); img_mtx.invert(); //注意这里 // 用我们的渲染器画圆 ras.add_path(ccell); agg::render_scanlines(ras,sl,my_renderer); }</pic_span_gen_type></agg::pixfmt_bgr24></agg::rgba8></agg::int8u></agg::rgba8> |
显示效果
(转)用AGG实现高质量图形输出(三)的更多相关文章
- (转)用AGG实现高质量图形输出(二)
本文上接<用AGG实现高质量图形输出(一)>,分别介绍了AGG显示流程中的各个环节. 上次讲了AGG的显示原理并举了一个简单的例子,这一篇文章开始讲AGG工作流程里的每个环节.为了方便对照 ...
- (转)用AGG实现高质量图形输出(四)
AGG的字符输出 字符输出,对于AGG来说,这个功能可以处于显示流程的 不同位置.比如字体引擎可直接处于“Scanline Rasterizer”层向渲染器提供已处理完毕的扫描线,也可以处于“Vert ...
- (转)用AGG实现高质量图形输出(一)
AGG是一个开源.高效的跨平台2D图形库.AGG的功能与GDI+的功能非常类似,但提供了比GDI+更灵活的编程接口,其产生的图形的质量也非常高(自称超过GDI+) 使用前AGG的准备工作 下载AGG库 ...
- 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可以创建高质 ...
随机推荐
- Yii笔记---redirect重定向
Yii的redirect方法在CControler与CHttpRequest之中都有被定义,CController中的redirect调用了CHttpRequest中的redirect方法.我们平常调 ...
- 20+富有创意的BuddyPress网站
如果你想构建自己的社区网站,如果你熟悉WordPress,那么用BuddyPress构建它吧!它确实太强大了,本文整理了20个富有创意的BuddyPress网站,看看它们,你也能拥有! 原文地址:ht ...
- LeetCode(6) - ZigZag Conversion
这个题的要求是给你一个字符串,和一个行数,例如(s = "mysisteristhemostlovelygirl" , row = 4),每一行一个字符串,但是s却得按照zigza ...
- 开始使用Ambari吧
最开始接触Hadoop是研究生入学后,帮师姐装装集群什么的.过程很繁琐,很重复,很是让人抓狂.当时装一个三台机器的集群需要两天左右,这还是装的很熟练的时间花费,刚入手的时候简直是惨不忍睹,三台机器装了 ...
- QueryInterface
QueryInterface IUnknown *p2; hr = pInnerUnknown->QueryInterface(vGUID2, (void**)&p2); IUnknow ...
- printf输出字符串的一些格式
1. 原样输出字符串: printf("%s", str); 2. 输出指定长度的字符串, 超长时不截断, 不足时右对齐: printf("%Ns" ...
- 下拉框QComboBox相关函数
QComboBox addItem (self, QString text, QVariant userData = QVariant())addItem (self, QIcon icon, QSt ...
- POJ2155Matrix(二维线段树)
链接http://poj.org/problem?id=2155 题目操作就是说,每次操作可以是编辑某个矩形区域,这个区域的0改为1,1改为0,每次查询只查询某一个点的值是0还是1. 方法:二维线段树 ...
- HDU 5708 Alice and Bob (博弈,找规律)
题意: 一个无限大的棋盘,一开始在1,1,有三种移动方式,(x+1,y)(x,y+1) (x+k,y+k)最后走到nm不能走了的人算输.. 析:.我们看成一开始在(n,m),往1,1,走,所以自然可以 ...
- 在VSTO界面中,调用xll中的函数
最近研究各种有点迷茫了,原来Xll的加载宏直接可以在C#中调用的,我又各种Out了. 先说明一下,在VBA中,如何调用吧 XLLFound = Application.RegisterXLL(This ...