【问题标题】:Image created using Gdk::Pixbuf is garbled upon display使用 Gdk::Pixbuf 创建的图像在显示时出现乱码
【发布时间】:2019-05-23 17:34:26
【问题描述】:
  1. 我正在尝试在窗口中显示图像。
  2. 我将 C++ 与 Gtkmm 和 Gdkmm 库一起使用。
  3. 我从磁盘读取图像并创建 Gdk::Pixbuf
  4. 然后我将它显示在一个小部件中。这是我在屏幕上看到的:

  1. 实际图像应该是这样的:

C++代码如下:

template <typename type>
Glib::RefPtr<Gdk::Pixbuf> get_pixbuf_from_image(array<type>& image){

  // Get dimensions of image
  vlong img_dims = image.get_dims();

  // Get number of elements and multiply by the number of channels
  vlong rgb_dims{3*static_cast<long>(image.get_size())};

  // Create a new RGB array of type <guint8> 
  array<guint8> image_rgb(rgb_dims);

  // Find maximum and minimum pixel value of image.
  type maximum = -1E6;
  type minimum =  1E6;
  for(int i=0; i<image.get_size(); i++){
    maximum = (image.data[i] > maximum) ? image.data[i] : maximum;
    minimum = (image.data[i] < minimum) ? image.data[i] : minimum;
  }

  // Rescale pixel values to [0, 255], and store in RGB array.
  for(int i=0; i<image.get_size(); i++){
      image_rgb.data[3*i+0] = guint8(254*(image.data[i]-minimum)/(maximum-minimum)); // Red channel
      image_rgb.data[3*i+1] = guint8(254*(image.data[i]-minimum)/(maximum-minimum)); // Green channel
      image_rgb.data[3*i+2] = guint8(254*(image.data[i]-minimum)/(maximum-minimum)); // Blue channel
  }

  // Create a Pixbuf from (guint8*)image_rgb.data 
  Glib::RefPtr<Gdk::Pixbuf> Pixbuf_from_data(Gdk::Pixbuf::create_from_data(image_rgb.data, Gdk::COLORSPACE_RGB, false, BITS_PER_SAMPLE, img_dims[1], img_dims[0], 3*img_dims[1]*sizeof(guint8)));

  // Save Pixbuf to PNG file.                                                              
  Pixbuf_from_data->save("picture.png", "png");

  // Return Pixbuf to caller for displaying. 
  return Pixbuf_from_data;
}

这里有一些背景信息:

  1. 保存的 PNG 文件没有乱码 - 它看起来应该是这样!问题似乎出在显示器上。

  2. 我在两个系统(MacOS 和 Debian)上尝试了相同的代码。问题只出在Debian系统上(MacOS显示右图)。

  3. 我在两个系统中使用相同的库,但使用不同版本的 g++ 编译器。

  4. 如果我从 PNG 文件创建 Pixbuf,则显示的图像再次正确。


有没有办法解决问题?我错过了什么吗?

【问题讨论】:

  • 你在两个系统上都有什么版本的 gtk+?
  • 我在两个系统上都使用 gtk+3。
  • 文档没有说任何一种方式,但我猜Gdk::Pixbuf::create_from_data 不会复制数据,image_rgb 在函数末尾超出范围,而您的 Pixbuf 是指着垃圾。

标签: c++ gtkmm3 gdkpixbuf


【解决方案1】:

Gdk::Pixbuf::create_from_data 不会复制数据。 image_rgb 在函数结束时超出范围,然后 Pixbuf 指向垃圾数据。

最简单的解决方法是在您返回 Pixbuf 时复制它:

return Pixbuf_from_data.copy()

这会复制PixBuf 对象拥有的数据。您可以通过在堆上分配数据并在 PixBuf 被销毁时使用 const SlotDestroyData&amp; destroy_slot 参数将其删除来避免复制。

【讨论】:

  • 谢谢,这似乎是问题所在!我完全错过了这个。
猜你喜欢
  • 1970-01-01
  • 2022-07-18
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多