Отображение изображения RGB в GTK + -2.2 - PullRequest
0 голосов
/ 09 ноября 2010

Я пишу класс, который может брать мои собственные изображения RGB и отображать их в окнах, используя GTK + -2.2.Мой класс Image хранит изображения в виде упакованных 24-битных RGB-байтов, поэтому преобразование должно быть тривиальным.Я использую метод gdk_draw_rgb (...) для рисования в моем окне, но ничто не рисуется вообще - окно просто отображается серым.

Я заставил это работать с помощью Каира, к сожалению, Каир можеттолько представляют изображения в формате 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 ]

1 голос
/ 09 ноября 2010

Чтобы отобразить (на стороне клиента) изображение, я думаю, вам следует изучить использование виджета <a href="http://library.gnome.org/devel/gtk/stable/GtkImage.html" rel="nofollow">GtkImage</a>, а не "перегружать" случайный виджет для выполнения пользовательского рисования.

Это, в свою очередь, откроет<a href="http://library.gnome.org/devel/gdk-pixbuf/unstable//gdk-pixbuf-gdk-pixbuf.html#GdkPixbuf" rel="nofollow">GdkPixbuf</a> с пикселями.

1 голос
/ 09 ноября 2010
gdk_draw_rgb_image(
  gtk_widget_get_root_window(window),

Это твоя проблема. В терминологии X (от которой GTK + сильно заимствует) «корневое окно» относится к фону рабочего стола. Вы хотите gtk_widget_get_window, который даст вам GdkDrawable, который представляет ваше окно.

Однако ... я не очень далеко поднялся по стеку от строки выше, и я не уверен, как выглядит вызывающая сторона этого кода, но вы обычно хотите рисовать в обработчике "события expose", а не сразу после звонка gtk_window_new. В прошлый раз, когда я писал этот вид кода (я должен признать, это было какое-то время), я бы создал GdkPixmap для рисования и затем скопировал его содержимое в видимый пользователю GdkWindow на выставить событие. Здесь полезен виджет GtkDrawingArea, поэтому я искал бы примеры, используя это.

...