使用Cairo旋转并保存PNG图像

时间:2012-08-06 19:01:39

标签: c graphics 2d cairo

我正在编写一个需要执行以下操作的小型演示应用程序:

  1. 请参阅参考PNG图片文件
  2. PNG图像旋转x度数
  3. 将新图像另存为动画帧
  4. 使用最后一次旋转的结果返回步骤2直到完成旋转。
  5. 结果应该是一系列PNG图像文件,显示不同旋转度的图像。然后,这些图像将以某种方式组合成电影或动画GIF

    我创建了以下代码,尝试进行一次旋转:

    #include <cairo.h>
    #include <math.h>
    
    /**** prototypes *******/
    void Rotate( cairo_surface_t *image, int degress, const char *fileName );
    double DegreesToRadians( double degrees );
    /***********************/
    
    double DegreesToRadians( double degrees )
    {
        return((double)((double)degrees * ( (double)M_PI/(double)180.0 )));
    }
    
    void Rotate( cairo_surface_t *image, int degrees, const char *fileName )
    {
        int w, h;
        cairo_t *cr;
    
        cr = cairo_create(image);
        w = cairo_image_surface_get_width (image);
        h = cairo_image_surface_get_height (image);
    
        cairo_translate(cr, w/2.0, h/2.0);
        cairo_rotate(cr, DegreesToRadians( degrees ));
        cairo_translate(cr, - w/2.0, -h/2.0);
    
        cairo_set_source_surface(cr, image,  0, 0);
        cairo_paint (cr);
    
    
        cairo_surface_write_to_png(image, fileName );
        cairo_surface_destroy (image);
        cairo_destroy(cr);  
    }
    
    int main()
    {
        cairo_surface_t *image = cairo_image_surface_create_from_png ("images/begin.png");
        Rotate(image, 90, "images/end.png");
        return( 0 );
    }
    

    问题是原始图像旋转90度后,生成的保存图像会旋转但不完全正确。我已经尝试重新排列cairo调用的顺序,这可能与表面状态或上下文有关。

    开始和结束图像如下所示:

    Results

    我错过了什么?

1 个答案:

答案 0 :(得分:4)

您打开原始图像作为要绘制的表面。打开原始.png并通过cairo_set_source_surface将其用作,并将其绘制到通过cairo_image_surface_create创建的新的图像表面上。

首先替换:

cr = cairo_create(image);
w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);

使用:

w = cairo_image_surface_get_width (image);
h = cairo_image_surface_get_height (image);
cairo_surface_t* tgt = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);

cr = cairo_create(tgt);

然后,当然,您需要保存tgt,而不是image,以进行归档,并进行清理。