我正在尝试在窗口中显示图像。
我正在将C ++与Gtkmm和Gdkmm库一起使用。
我从磁盘读取图像并创建一个Gdk :: Pixbuf
然后,我将其显示在小部件中。这是我在屏幕上看到的:


c++ - 使用Gdk::Pixbuf创建的图像在显示时出现乱码-LMLPHP


实际的图像应该看起来像这样:


c++ - 使用Gdk::Pixbuf创建的图像在显示时出现乱码-LMLPHP

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;
}




以下是一些背景信息:


保存的PNG文件没有乱码-看起来应该正确!问题似乎只在于显示器。
我在两个系统(MacOS和Debian)上尝试了相同的代码。问题仅在Debian系统上(MacOS显示正确的图片)。
我在两个系统上使用相同的库,但是使用不同版本的g ++编译器。
如果我改用PNG文件创建Pixbuf,则显示的图像再次正确。




有办法解决问题吗?我想念什么吗?

最佳答案

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

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

return Pixbuf_from_data.copy()


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

关于c++ - 使用Gdk::Pixbuf创建的图像在显示时出现乱码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56280340/

10-11 22:25