首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用cairo旋转图像Gtk 3

用cairo旋转图像Gtk 3
EN

Stack Overflow用户
提问于 2018-04-11 23:35:08
回答 1查看 519关注 0票数 1

我试图得到一个随机位置的图像旋转。我在看另一个类似的帖子(旋转图像)。但我没办法把事情做好。

代码语言:javascript
复制
#include <gtk/gtk.h>
#include <cairo.h>

GtkWidget *window;

static void rotate_cb()
{
    gtk_widget_queue_draw(window);

}

static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
    GtkWidget *img = (GtkWidget *)(data);
    gint w = gtk_widget_get_allocated_width (img);
    gint h = gtk_widget_get_allocated_height (img);
    gtk_widget_realize(img);
    cairo_surface_t *surface = gdk_window_create_similar_surface(gtk_widget_get_window (img), CAIRO_CONTENT_COLOR, w, h);
    cairo_t *cr = cairo_create (surface);

    cairo_translate(cr, w/2, h/2);
    cairo_rotate(cr, 2);
    cairo_set_source_surface(cr, surface, -w/2, -h/2);

    cairo_paint(cr);
    cairo_destroy(cr);
    cairo_surface_destroy(surface);
    return FALSE;
}


int main(int argc, char *argv[])
{   
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 600, 600);
    gtk_widget_set_app_paintable(window, TRUE);
    GtkWidget *l = gtk_layout_new(NULL, NULL);
    gtk_container_add(GTK_CONTAINER(window), l);
    GtkWidget *img = gtk_image_new_from_file("example.png");
    gtk_layout_put(GTK_LAYOUT(l), img, 300, 300);

    g_signal_connect(window, "draw", G_CALLBACK (on_expose_event), img);
    g_signal_connect(window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

    GtkWidget *button = gtk_button_new_with_label("button");
    g_signal_connect(button, "clicked", G_CALLBACK(rotate_cb), NULL);
    gtk_layout_put(GTK_LAYOUT(l), button, 0, 0);

    gtk_widget_show_all(window);
    gtk_main();
}

窗口确实收到了绘图信号,但我不知道如何连接gtkwidget和cairo_surface_t。

或者也许有更好的方法来做到这一点(没有开罗)。我喜欢各种各样的想法!谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-12 16:19:27

GtkWidget draw信号处理程序的原型应该是:

代码语言:javascript
复制
gboolean user_function (GtkWidget *widget, CairoContext *cr, gpointer user_data)

文档所述

这个信号是在小部件应该呈现自己时发出的。小部件的左上角必须在上下文中传递的起始处绘制,大小必须调整为gtk_widget_get_allocated_width()和gtk_widget_get_allocated_height()返回的值。 连接到该信号的信号处理程序可以以他们喜欢的任何方式修改作为cr传递的cairo上下文,并且不需要恢复它。信号发射负责在调用处理程序之前调用cairo_save()和调用cairo_restore()。 信号处理程序将得到一个cr,其中的剪辑区域已经设置为小部件的脏区域,即需要重新绘制的区域。想要避免完全重绘自己的复杂小部件可以使用gdk_cairo_get_clip_rectangle()获得剪辑区域的全部范围,也可以使用cairo_copy_clip_rectangle_list()获得脏区域的更细粒度的表示。参数 小部件-接收信号的对象 cr -要绘制的开罗上下文 user_data -连接信号处理程序时的用户数据集。

因此,您的on_expose_event函数原型必须更改,开罗上下文将提供给您:

代码语言:javascript
复制
static gboolean on_expose_event(GtkWidget *widget, cairo_t *cr, gpointer data)
{
.... // your code must change too
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49785861

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档