如何使用GTK + / Cairo旋转图像 [英] How to rotate image using GTK+ / Cairo

查看:193
本文介绍了如何使用GTK + / Cairo旋转图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的应用程序,它应该使用 GTK + Cairo 。我在下面有一些代码从计时器中调用 cairo_rotate()。但是,图像不会改变。我是否必须使图像无效才能使曝光事件触发?我对开罗很陌生,在 GTK + 中使用 Cairo 来演示如何旋转图像的简单例子会非常高赞赏。

I've got a simple application that is supposed to rotate a decorated wheel so many degrees every x number of milliseconds using GTK+ and Cairo. I've got some code below that calls cairo_rotate() from a timer. However, the image doesn't change. Do I have to invalidate the image to cause the expose-event to fire? I'm so new to Cairo that a simple example demonstrating how to rotate an image using Cairo in GTK+ would be highly appreciated.

#include <cairo.h>
#include <gtk/gtk.h>

cairo_surface_t *image;
cairo_t *cr;


gboolean rotate_cb( void )
{

    cairo_rotate (cr, 1);
    //cairo_paint(cr);
    printf("rotating\n");

    return( TRUE );
}

static gboolean
on_expose_event(GtkWidget *widget,
    GdkEventExpose *event,
    gpointer data)
{
  cr = gdk_cairo_create (widget->window);

  cairo_set_source_surface(cr, image, 0, 0);
  cairo_paint(cr);
  printf("Paint\n");

  //cairo_destroy(cr);

  return FALSE;
}


int main(int argc, char *argv[])
{
  GtkWidget *window;

  image = cairo_image_surface_create_from_png("wheel.png");

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

  g_signal_connect(window, "expose-event",
      G_CALLBACK (on_expose_event), NULL);
  g_signal_connect(window, "destroy",
      G_CALLBACK (gtk_main_quit), NULL);

  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 500, 500); 
  gtk_widget_set_app_paintable(window, TRUE);

  gtk_widget_show_all(window);
  g_timeout_add(500, (GSourceFunc) rotate_cb, NULL);

  gtk_main();
  cairo_destroy(cr);
  cairo_surface_destroy(image);

  return 0;
}


推荐答案

在一个变量中,并把cairo_rotate(cr,rotation_amt);在绘制之前调用on_expose_event方法。

You need to store the rotation in a variable and put the cairo_rotate(cr, rotation_amt); call into the on_expose_event method, before paint.

如果图像居中,也转换到窗口中心,旋转并翻转回来,以使轮子围绕它的中心旋转。

Also translate to the center of the window, rotate, and translate back, to make the wheel rotate around it's center, if the image is centered.

cairo_translate(cr, width / 2.0, height / 2.0);
cairo_rotate(cr, rotation_amt);
cairo_translate(cr, - image_w / 2.0, - image_h / 2.0);
cairo_set_source_surface(cr, image, 0, 0);
cairo_paint(cr);

我希望是的。

正如ptomato所说,您需要通过从rotate_cb调用gtk_widget_queue_draw来使绘图表面无效。保持开罗上下文的全局变量是多余的。图片不会旋转,因为新创建的上下文会使用单位矩阵加载,并且您以前的所有转换都将重置。

And as ptomato said, you need to invalidate your drawing surface by calling gtk_widget_queue_draw from rotate_cb. And keeping a global variable for the Cairo context is redundant. The image doesn't rotate because a newly created context is loaded with an identity matrix and all your previous transformations are reset.

这篇关于如何使用GTK + / Cairo旋转图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆