AGG第四十三课 例子image1从椭圆到矩形替换问题

I am basing my code on the images1 example and I have changed

the image ‘partner‘ shape from an ellipse to a rectangle.

The partner rectangle comes out at X,Y and scales and rotates,

but the top left-hand corner of the image is always stuck at

(x,y)=3D(0,0). Only the part of the image that overlaps the=20

rectangle is visible, but that part scales and rotates properly.=20

When there is no overlap, there is no image.

I do not understand much of the the image1 example, so I am

lost as to what might be.the cause. Code is attached.

Would be most grateful for help and/or example code.

void image ( HAGG * h , int x , int y , TCHAR * imgfilename )

{

if ( !loadimage ( h , imgfilename ) ) // sets image details in h

{

return ;

}

agg::rendering_buffer rbuf(h->pixels ,

h->frame_width ,=20

h->frame_height ,=20

-(h->frame_width * h->bytesperpixel) ) ;=20

typedef agg::renderer_base<pixfmt>                     renderer_base;

typedef agg::renderer_base<pixfmt_pre>                 =

renderer_base_pre;

typedef agg::renderer_scanline_aa_solid<renderer_base> =

renderer_solid;

pixfmt            pixf(rbuf);

pixfmt_pre        pixf_pre(rbuf);

renderer_base     rb(pixf);

renderer_base_pre rb_pre(pixf_pre);

renderer_solid    rs(rb);

rb.clear(agg::rgba(1.0, 1.0, 1.0));

agg::rasterizer_scanline_aa<> pf;

agg::scanline_u8 sl;

IMGINFO * i =3D &h->imgs [ 0 ] ;

double imgwd =3D i->width ;       // image width

double imght =3D i->height  ;     // image height

agg::trans_affine src_mtx;

src_mtx *=3D agg::trans_affine_translation(-x,-y);

src_mtx *=3D agg::trans_affine_rotation(-h->t.angle);  // in radians

src_mtx *=3D agg::trans_affine_scaling(h->t.scalex , h->t.scaley);

src_mtx *=3D agg::trans_affine_translation(x,y);

agg::trans_affine img_mtx;

img_mtx *=3D agg::trans_affine_translation(-x,-y);

img_mtx *=3D agg::trans_affine_rotation(-h->t.angle);

img_mtx *=3D agg::trans_affine_scaling(h->t.scalex , h->t.scaley);

img_mtx *=3D agg::trans_affine_translation(x,y);

img_mtx.invert();

typedef agg::span_allocator<color_type> span_alloc_type;

span_alloc_type sa;

typedef agg::span_interpolator_linear<> interpolator_type;

interpolator_type interpolator(img_mtx);

// "hardcoded" bilinear filter

typedef agg::span_image_filter_rgb_bilinear<color_type, =

component_order,=20

interpolator_type> =

span_gen_type;

typedef agg::renderer_scanline_aa<renderer_base_pre, span_gen_type> =

renderer_type;

agg::rendering_buffer rbuf_img(i->pixels ,

(int)imgwd ,=20

(int)imght ,=20

-i->stride ) ;=20

span_gen_type sg(sa,=20

rbuf_img,  // rendering buf with image pixels

agg::rgba_pre(0, 0.4, 0, 0.5),

interpolator);

renderer_type ri(rb_pre, sg);

agg::path_storage path; // partner rectangle

path.move_to( x,y);

path.line_to( x+imgwd, y );

path.line_to( x+imgwd, y+imght);

path.line_to( x, y+imght);

path.close_polygon();

agg::conv_transform<agg::path_storage> tr(path, src_mtx);

=20

pf.add_path(tr);

agg::render_scanlines(pf, sl, ri);

}

static void drawimage ( )

{

RECT rt ;

GetClientRect(hwndmain, &rt);

int width =3D rt.right - rt.left;

int height =3D rt.bottom - rt.top;

HAGG * h =3D gethandle ( mybuf , width , height , 4 ) ;

settrans_scale ( h , scale ) ;

settrans_rotate ( h , degrees ) ;

//   image ( h , 20,50 , "bmpeivor.bmp"  ) ; // does not work

image ( h , 0,0 , "bmpeivor.bmp"  ) ;  // works

display ( h , hwndmain ) ;  // on screen

}

作者的回答:

Transforming images is tricky, especially proper calculation of the affine

matrix.

But first, if you don‘t need to transform it you can directly copy or blend

the image, it will work much faster. See renderer_base<>::copy_from(),

blend_from().

For the transformer there‘s a simple way of calculating the matrix as a

parallelogram, see image_perspective.cpp

// Note that we consruct an affine matrix that transforms

// a parallelogram to a rectangle, i.e., it‘s inverted.

// It‘s actually the same as:

// tr(0, 0, img_width, img_height, para); tr.invert();

agg::trans_affine tr(para, 0, 0, img_width, img_height);

Where "para" is double[6] that defines 3 point of the parallelogram.

困惑:

I have replaced

agg::path_storage path; // partner rectangle

path.move_to( x,y);

path.line_to( x+imgwd, y );

pathmline_to( x+imgwd, y+imght);

path.line_to( x, y+imght);

path.close_polygon();

agg::conv_transform<agg::path_storage> tr(path, src_mtx);

pf.add_path(tr);

agg::render_scanlines(pf, sl, ri);

at the and of my image proc (code of the whole proc is at

the end of my original post (and at the end of this email))

by

double para [ 6 ]

= { 0,100 ,  0,0 , 100.0 } ; // 3 points (0,100) (0,0) and (100,0)

agg::trans_affine tr(para, 0, 0, imgwd, imght);

pf.add_path(tr);

agg::render_scanlines(pf, sl, ri);

Q1.   is this the right way?

Q2.  what should the para points be expressed as functions of

image top-left hand corner, image width and image height, i.e.

x,y, imgwd, imght?

My test cases includes image (x,y)=(0,0), so I defined para points

(0,100), (0,0) and (100,0) just to see what would happen.

but got compilation errors:

..\agg23\include\agg_rasterizer_scanline_aa.h(465) : error C2039: ‘rewind‘ :

is not a member of ‘trans_affine‘

..\agg23\include\agg_trans_affine.h(88) : see declaration of

‘trans_affine‘

and one more very similar:  ‘vertex‘ : is not a member of ‘trans_affine‘

作者的回答:

> double para [ 6 ] = { 0,100 ,  0,0 , 100,0 } ; // 3 points (0,100) (0,0)

> and (100,0)

> agg::trans_affine mtx(para, 0, 0, imgwd, imght);

> agg::path_storage path; // partner rectangle

> path.move_to( x,y);

> path.line_to( x+imgwd, y );

> path.line_to( x+imgwd, y+imght);

> path.line_to( x, y+imght);

> path.close_polygon();

> agg::conv_transform<agg::path_storage, agg::trans_affine> trans(path,

> mtx);

>

> pf.add_path(trans); // Note you add "trans"

>

> Then, if you want your image to fit exactly your parallelogram path (you

> also may want to do differently!), you need to create a copy of the matrix

> and invert it:

>

> agg::trans_affine img_mtx(mtx);

> img_mtx.invert();

I‘m sorry, Ken, this is not correct; I have confused myself, so, please

discard the code above. :)

So, suppose you have an image of imgwd, imght and a destination

parallelogram. To define the parallelogram you need 3 points, x1,y1 - bottom

left, x2,y2 - bottom right, x3,y3 - top right. The parallelogram can also

define a 2D affine matrix: rotation, scaling, translation and skewing. You

can rasterize your destination parallelogram directly:

agg::rasterizer_scanline_aa<> ras;

ras.move_to_d(x1,y1);

ras.line_to_d(x2,y2);

ras.line_to_d(x3,y3);

ras.line_to_d(x1 + x3 - x2, y1 + y3 - y2);

So that, you can draw a solid parallelogram (well, you can also use the

path_storage if you want).

To map an image to it you need to create the matrix:

double para[6] = {x1,y1,x2,y2,x3,y3};

agg::trans_affine img_mtx(0, 0, imgwd, imght, para);

img_mtx.invert();

Or, which is the same:

double para[6] = {x1,y1,x2,y2,x3,y3};

agg::trans_affine img_mtx(para, 0, 0, imgwd, imght);

The first one construicts a matrix to transform a rectangle to a a

parellelogram, the second one - parallelogram to rectangle. The image

transformer requires namely inverse matrix, so that, you transform your

parallelogram (destination) to rectangle (image).

Technically that‘s it. But you may want to apply additional transformations.

To do that you will need two matrices:

agg::trans_affine master_mtx;

master_mtx *= agg::trans_affine_translation(. . .);

master_mtx *= agg::trans_affine_rotation(. . .);

. . .

agg::rasterizer_scanline_aa<> ras;

agg::path_storage path; // partner rectangle

path.move_to(x1,y1);

path.line_to(x2,y2);

path.line_to(x3,y3);

path.line_to(x1 + x3 - x2, y1 + y3 - y2);

path.close_polygon();

agg::conv_transform<agg::path_storage, agg::trans_affine> trans(path,

master_mtx);

Then you prepare the image matrix:

double para[6] = {x1,y1,x2,y2,x3,y3};

agg::trans_affine img_mtx(0, 0, imgwd, imght, para);

img_mtx *= master_mtx; //!!!!!!!!!!!!! Integrate the master transforms

img_mtx.invert();

ras.add_path(trans);

. . .Render

Now, whatever transformations you use in the master_mtxà they will be

synchronized with the image.

Sorry for the delay, I was kinda busy last time. and besides, I‘m suffering

from constant problems with the Internet (Verizon in NYC sucks, I‘m

switching to cable).

Well, I understand everyone is busy, but could someone else answer the

questions too?

First, you need to understand that a path is the primary thing in AGG.

Without path you can‘t draw anything. So that, to rotate an image you need

to create a respective path as if you wanted to fill this area with a solid

color. And then, you just substitute an image renderer for your solid fill.

Obviously, to transform the whole image you need to create a parallelogram

path (a rectangle in particular). You can do that calculating the points

manually:

ras.move_to_d(x1, y1);

ras.line_to_d(x2, y2);

. . .

You you can use transformations.

Next, trans_affine doesn‘t have any "VertexSource" interface, it can‘t

generate vertices. It can only transform them: affine.transform(&x, &y); To

add affine transformer into your pipeline you also need conv_transform:

double para [ 6 ] = { 0,100 ,  0,0 , 100,0 } ; // 3 points (0,100) (0,0) and

(100,0)

agg::trans_affine mtx(para, 0, 0, imgwd, imght);

agg::path_storage path; // partner rectangle

path.move_to( x,y);

path.line_to( x+imgwd, y );

path.line_to( x+imgwd, y+imght);

path.line_to( x, y+imght);

path.close_polygon();

agg::conv_transform<agg::path_storage, agg::trans_affine> trans(path, mtx);

pf.add_path(trans); // Note you add "trans"

Then, if you want your image to fit exactly your parallelogram path (you

also may want to do differently!), you need to create a copy of the matrix

and invert it:

agg::trans_affine img_mtx(mtx);

img_mtx.invert();

Well, I realize that it all is pretty confusing. But this kind of a design

is most flexible.

摘自:http://sourceforge.net/p/vector-agg/mailman/vector-agg-general/?viewmonth=200511&page=0

时间: 2024-08-28 11:56:19

AGG第四十三课 例子image1从椭圆到矩形替换问题的相关文章

NeHe OpenGL教程 第四十三课:FreeType库

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十三课:FreeType库 在OpenGL中使用FreeType库 使用FreeType库可以创建非常好看的反走样的字体,记住暴雪公司就是使用这个库的,就是那个做魔兽世界的.尝试一下吧,我只告诉你了基本的使用方式,你可以走的更远

第四十三课:jQuery插件化

我们先来看一个最简单的例子: (function($){ $.fn.extend({     //把此插件添加到jQuery的原型上 pluginName:function(){   //插件的名字 return this.each(function(){     //遍历匹配元素的集合 //插件要实现的功能 }); } }); })(jQuery);   //传入jQuery对象 由于jQuery是集化操作($("div")会选择多个div元素进行操作),而我们的插件编写应该一个元素

AGG第三十三课 line_profile_aa 参数分析说明

1 前言 agg::line_profile_aa是agg::renderer_outline_aa渲染线段的属性设置类,aa就是anti-aliased的意思,具有抗锯齿功能. 2 函数功能说明 如下简单介绍一下对于线段的属性设置,主要是调用agg::line_profile_aa对象的成员函数: agg::line_profile_aa::min_width() 字面上理解就是设置最小线宽.如果指定的线宽小于min_width函数的设置值,线段将会被化成透明色(brightness fadi

第四十三课

webapp  server与java技术基础 java技术基础及tomcat入门 tomcat配置详解 tomcat配置及案例

JAVA学习第四十三课 — 集合框架工具类(一)

一.Collections:集合框架的工具类 其中的方法都是静态的 排序方法演示 import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; class ComparaByLeng implements Comparator<String>{ public int compare(String o1, String o2) { int

AGG第四十课 SVG 使用的三种管道

The current version of SVG contains 3 pipelines: Simple polygons: path_storage -> conv_curve -> conv_transform -> conv_clip Strokes: path_storage -> conv_curve -> conv_stroke -> conv_transform -> conv_clip Contoured polygons: path_sto

python第四十三课——封装性

1.面向对象的三大特性:封装性.继承性.多态性 封装: 封装使用的领悟: 1).生活层面:食品.快递.计算机.明星... 2).计算机层面: ①.模块.类.函数... ②.属性数据的封装与隐藏 权限修饰符的概念: public(公共的,范围最大) protected(收保护的)default(默认,缺省) private(私有的,范围最小) python语言没有以上这些关键字: 对于python的属性私有化使用:__来实现 在设计完类,外界创建对象通过.的形式访问(设置)属性, 可能会出现跟现实

AGG第二十六课 裁剪功能

AGG有四种类型的裁剪,分别工作在不同的层次 1. 基础渲染器Base Render 除非直接调用基础渲染器的绘制线段的方法,否则在一般情况下,都是在render_scanline的时候被调用,进行裁剪,这个时候已经进行了大量无用的工作.比如顶点源超出屏幕范围,在调用render_scanline函数之前,比如调用rasterizer对象的add_path函数,已经浪费大量的资源 2 光栅器rasterizer rasterizer主要应用于根据顶点源,生成线段的详细信息,这个时候调用裁剪,可以

NeHe OpenGL教程 第三十三课:TGA文件

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十三课:TGA文件 加载压缩和未压缩的TGA文件: 在这一课里,你将学会如何加载压缩和为压缩的TGA文件,由于它使用RLE压缩,所以非常的简单,你能很快地熟悉它的. 我见过很多人在游戏开发论坛或其它地方询问关于TGA读取的问题.