|
From: Maxim S. <mc...@an...> - 2005-11-17 14:42:51
|
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.
McSeem
"Ken Resander" <res...@sp...> wrote in message
news:001601c5eb0e$5e02d2c0$411faccb@KENXP...
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)=(0,0). Only the part of the image that overlaps the
rectangle is visible, but that part scales and rotates properly.
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.
Best regards
Ken
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 ,
h->frame_height ,
-(h->frame_width * h->bytesperpixel) ) ;
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 = &h->imgs [ 0 ] ;
double imgwd = i->width ; // image width
double imght = i->height ; // image height
agg::trans_affine src_mtx;
src_mtx *= agg::trans_affine_translation(-x,-y);
src_mtx *= agg::trans_affine_rotation(-h->t.angle); // in radians
src_mtx *= agg::trans_affine_scaling(h->t.scalex , h->t.scaley);
src_mtx *= agg::trans_affine_translation(x,y);
agg::trans_affine img_mtx;
img_mtx *= agg::trans_affine_translation(-x,-y);
img_mtx *= agg::trans_affine_rotation(-h->t.angle);
img_mtx *= agg::trans_affine_scaling(h->t.scalex , h->t.scaley);
img_mtx *= 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,
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 ,
(int)imght ,
-i->stride ) ;
span_gen_type sg(sa,
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);
pf.add_path(tr);
agg::render_scanlines(pf, sl, ri);
}
static void drawimage ( )
{
RECT rt ;
GetClientRect(hwndmain, &rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
HAGG * h = 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
}
|