这是我尝试的内容:
#include <gtk/gtk.h>
static GtkWidget *window, *drawing_area;
static gboolean drawCallback(GtkWidget *widget, cairo_t *cr, gpointer arg) {
cairo_set_source_rgb(cr, 1.0, 0, 0);
cairo_arc(cr, 200.0, 150.0, 50.0, 0, 2*G_PI);
cairo_fill(cr);
}
static gboolean savePNG(gpointer arg) {
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_RGB24, 400, 300
);
cairo_t *cr = cairo_create(surface);
gdk_cairo_set_source_window(
cr,
gtk_widget_get_window(GTK_WIDGET(window)),
0, 0
);
printf("cairo_status(cr): %s\ncairo_surface_status(surface): %s\n",
cairo_status_to_string(cairo_status(cr)),
cairo_status_to_string(cairo_surface_status(surface)));
cairo_surface_write_to_png(surface, "test.png");
}
static void app_activate(GtkApplication *app, gpointer user_data) {
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Sandbox");
gtk_widget_set_size_request(GTK_WIDGET(window), 400, 300);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawCallback), NULL);
gtk_widget_show_all(window);
gtk_window_move(GTK_WINDOW(window), 10, 10);
}
int main(int argc, char **argv) {
GtkApplication *app;
int status;
app = gtk_application_new("the.application.id", G_APPLICATION_FLAGS_NONE);
g_signal_connect(app, "activate", G_CALLBACK(app_activate), NULL);
g_timeout_add(1000, savePNG, NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}
窗口显示一个红色圆圈,但创建的 test.png 文件包含全黑图像。
这是输出:
cairo_status(cr): no error has occurred
cairo_surface_status(surface): no error has occurred
This answer提出了我使用过的模式。
答案 0 :(得分:1)
在保存之前,你忘了在表面上画任何东西。
static gboolean savePNG(gpointer arg)
{
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 300, 200); // <<= Reduced size to get only a part of the window.
cairo_t *cr = cairo_create(surface);
cairo_translate(cr, -50.0, -50.0); // <<= Move the part we want to copy from source into position....
gdk_cairo_set_source_window(
cr,
gtk_widget_get_window(GTK_WIDGET(window)),
0, 0
);
cairo_paint(cr); // <<= DO IT! ;)
cairo_surface_write_to_png(surface, "test.png");
}
编辑:
我更新了代码,只将窗口的一部分复制到文件中。 您需要将源移动到所需窗口部分的新起点。当然,你的表面也需要更小。