在GTK + -2.2中显示RGB图像

时间:2010-11-09 04:28:56

标签: c++ image user-interface gtk gdk

我正在编写一个可以使用我自己的RGB图像并使用GTK + -2.2将它们显示到窗口的类。 My Image类将图像存储为打包的24位RGB字节,因此转换应该是微不足道的。我正在使用gdk_draw_rgb(...)方法绘制到我的窗口,但根本没有绘制任何东西 - 窗口只显示为灰色。

我确实使用Cairo工作,不幸的是开罗只能代表32bpp格式的图像,并且进行转换太慢了。

  class ImageDisplay
  {
    public:
      ImageDisplay();
      ~ImageDisplay();

      void showImage(Image img, std::string label="");

    private:
      std::thread _gtkThread;

      std::map<std::string, GtkWidget*> _windows;
  };

// ######################################################################
void gtkThreadMethod()
{
  g_thread_init(NULL);
  gdk_threads_init();
  gdk_threads_enter();

  int argc=1;
  char **argv = new char*;
  argv[0] = new char[8];
  sprintf(argv[0], "display");
  gtk_init(&argc, &argv);

  gdk_rgb_set_verbose(TRUE);

  gtk_main();

  gdk_threads_leave();
}

// ######################################################################
ImageDisplay::ImageDisplay()
{ 
  // Start gtk in its own thread
  _gtkThread = std::thread(gtkThreadMethod);
}

// ######################################################################
ImageDisplay::~ImageDisplay()
{  
  // Tell GTK that it's time to quit
  gdk_threads_enter();
  gtk_main_quit();
  gdk_threads_leave();

  // Wait for the thread to die
  _gtkThread.join();
}

// ######################################################################
void ImageDisplay::showImage(Image img, std::string label)
{
  gdk_threads_enter();

  // Create a new window if one doesn't yet exist
  if(_windows.find(label) == _windows.end())
  {
    GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), label.c_str());
    gtk_window_set_default_size(GTK_WINDOW(window), img.dims().w(), img.dims().h());
    gtk_widget_set_app_paintable(window, TRUE);
    gtk_window_set_resizable(GTK_WINDOW(window), true);
    GdkGeometry size_hints;
    size_hints.min_aspect = 1;
    size_hints.max_aspect = 1;
    gtk_window_set_geometry_hints(GTK_WINDOW(window), window,
        &size_hints, GDK_HINT_ASPECT);
    gtk_widget_show_all(window);
    _windows[label] = window;
  }

  GtkWidget* window = _windows[label];

  GdkGC *gc = gdk_gc_new(gtk_widget_get_root_window(window));
  gdk_draw_rgb_image(
      gtk_widget_get_root_window(window),
      gc,
      0, 0,
      img.dims().w(), img.dims().h(),
      GDK_RGB_DITHER_NORMAL, 
      (const unsigned char*)img.const_begin(), 
      img.dims().w()*3);

  gdk_threads_leave();
}

2 个答案:

答案 0 :(得分:1)

gdk_draw_rgb_image(
  gtk_widget_get_root_window(window),

有你的问题。在X术语(GTK +大量借用)中,“根窗口”指的是桌面背景。您希望gtk_widget_get_window能够获得代表您的窗口的GdkDrawable

但是......我没有从上面的行中走得很远,而且我不确定这段代码的调用者是什么样的,但是你通常想要绘制一个“曝光事件”处理程序,而不是在致电gtk_window_new后立即。我最后一次编写这种代码(已经有一段时间了,我会承认),我要做的是创建一个GdkPixmap来绘制,然后将其内容复制到用户可见的{{1暴露事件。 GdkWindow窗口小部件在这里很有用,所以我会使用它来搜索示例。

答案 1 :(得分:1)

要显示(客户端)图像,我认为您应该考虑使用GtkImage小部件,而不是“重载”随机小部件来进行自定义绘制。

这将反过来曝光GdkPixbuf持有像素。