[cairo] Rotation in cairo

Adrian Johnson ajohnson at redneon.com
Mon Aug 4 04:52:51 PDT 2008


Hung Nguyen Vu wrote:
> Hello all,
> 
> How can I rotate a surface in cairo around it's center?
> I've tried the following code but the output image( Flag-rotate.png) remains
> the same as Flag.png. I expect a rotation of M_PI/2.
 >
 > #include <cairo.h>
 > #include <math.h>
 > int main (int argc, char *argv[])
 > {
 >
 >  int w, h;
 >
 >   cairo_surface_t *image;
 >   cairo_t *cr;
 >
 >   image = cairo_image_surface_create_from_png ("Flag.png");
 >   cr = cairo_create (image);

The problem here is you are using your source surface as the destination 
surface. You need to create a separate surface to paint the source to.

 >
 >   w = cairo_image_surface_get_width (image);
 >   h = cairo_image_surface_get_height (image);
 >   cairo_translate (cr, w * 0.5, h * 0.5);
 >   cairo_rotate (cr, M_PI / 2.0);
 >   cairo_translate (cr, -w * 0.5, -h * 0.5);
 >   cairo_set_source_surface (cr, image, w*0.5, h*0.5);

You will probably want to leave the set_source_surface offset at 0, 0 
since you have already restored the origin to the original position 
after the rotation.

 >   cairo_surface_write_to_png (image, "Flag-rotate.png");

Here you are writing out the source image to a file. You should first 
paint the source to a destination surface then write the destination 
surface to a file.

 >
 >   cairo_paint (cr);
 >   cairo_surface_destroy (image);
 >
 >   return 0;
 >
 >
 > }
 >

Here's the updated code that correctly rotates the image. I have also 
swapped the width and height when creating the destination surface and 
in the first translate so that the rotated image fits exactly into the 
destination surface.

#include <cairo.h>
#include <math.h>
int main (int argc, char *argv[])
{

  int w, h;

   cairo_surface_t *image;
   cairo_surface_t *image2;
   cairo_t *cr;

   image = cairo_image_surface_create_from_png ("Flag.png");
   w = cairo_image_surface_get_width (image);
   h = cairo_image_surface_get_height (image);
   image2 = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, h, w);
   cr = cairo_create (image2);
   cairo_translate (cr, h * 0.5, w * 0.5);
   cairo_rotate (cr, M_PI / 2.0);
   cairo_translate (cr, -w * 0.5, -h * 0.5);
   cairo_set_source_surface (cr, image, 0, 0);
   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
   cairo_paint (cr);
   cairo_surface_write_to_png (image2, "Flag-rotate.png");
   cairo_surface_destroy (image);
   cairo_surface_destroy (image2);

   return 0;
}



More information about the cairo mailing list