在Gtk3的 DrawingArea中绘制image.png

编程语言 2026-07-08

我在GtkDrawingArea里尝试绘制一个.png图像,使用libgtk-3-0和 libcairo2。很简单,对吧?但我的代码出于某种原因失败了。

下面是我代码的精简版本。它可以通过下面的方法编译运行:

  • 把这里的代码拷贝到draw_png.c,
  • 把.png图像文件改成你电脑能访问的那一个,
  • 用第一行的gcc命令对其进行编译,
  • 然后运行可执行文件draw_png。

在我的电脑上,该代码能顺利编译并运行,但生成的窗口是空白的,没有图像。

请问这里的朋友能否
1.告诉我原因,或者
2.给我一个包含.png图像和GtkDrawingArea的“Hello world”风格的可工作代码?(我到处都找过,但没有找到这样的代码。)

/*compile with gcc -g3 draw_png.c -o draw_png `pkg-config gtk+-3.0 --cflags --libs`*/

#include <gtk/gtk.h>
#ifndef CAIRO_HAS_PNG_FUNCTIONS
printf("WARNING: Cairo has no .png functions\n");
#endif

/*---------------------------------------------------------------------*/
//draws image
gboolean draw_image(GtkWidget *drawing_area, cairo_t *cairo, gpointer data)
{
  cairo_surface_t *image_surface=NULL;
  char *filename="/home/mattor/Images/GTKIcon.png";

  image_surface=cairo_image_surface_create_from_png(filename);
  cairo_set_source_surface(cairo, image_surface, 0, 0);

  cairo_fill(cairo);

  printf("cairo status after calls is %s\n", cairo_status_to_string(cairo_status(cairo)));

  return FALSE;
}

/*---------------------------------------------------------------------*/

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

  gtk_init(&argc, &argv);

  //create window
  window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
  g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
  gtk_widget_show(window);

  //create drawing_area
  drawing_area = gtk_drawing_area_new();
  gtk_container_add(GTK_CONTAINER (window), drawing_area);
  g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(draw_image), NULL);
  gtk_widget_show(drawing_area);

  gtk_main();

  return 0;
}

解决方案

要使用 cairo_paint() 来显示图片,而不是 cairo_fill()

  cairo_set_source_surface(cairo, image_surface, 0, 0);
  cairo_paint(cairo);

你也可以使用 cairo_fill() 来绘制一个(例如绿色的)矩形。

  cairo_set_source_rgba(cairo, 0.0, 1.0, 0.0, 0.5);
  cairo_rectangle(cairo, 0, 0, 100, 100);
  cairo_fill(cairo);

用于测试的完整函数。

gboolean draw_image(GtkWidget *drawing_area, cairo_t *cairo, gpointer data)
{
  cairo_surface_t *image_surface = NULL;
  //char *filename = "/home/mattor/Images/GTKIcon.png";
  char *filename = "lenna.png";

  image_surface = cairo_image_surface_create_from_png(filename);
  cairo_set_source_surface(cairo, image_surface, 0, 0);
  cairo_paint(cairo);

  cairo_set_source_rgba(cairo, 0.0, 1.0, 0.0, 0.5);
  cairo_rectangle(cairo, 0, 0, 100, 100);
  cairo_fill(cairo);

  printf("cairo status after calls is %s\n", cairo_status_to_string(cairo_status(cairo)));

  return FALSE;
}

带有 lenna.png 和绿色矩形的窗口


维基百科:Lenna

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章