使用 Gdk::Pixbuf 创建的图像在显示时出现乱码
Image created using Gdk::Pixbuf is garbled upon display
- 我正在尝试在 window 中显示图像。
- 我将 C++ 与 Gtkmm 和 Gdkmm 库一起使用。
- 我从磁盘读取图像并创建 Gdk::Pixbuf
- 然后我将它显示在一个小部件中。这是我在屏幕上看到的内容:
- 实际图像应该是这样的:
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
指向垃圾数据。
最简单的解决方法是在 return 时复制 Pixbuf
:
return Pixbuf_from_data.copy()
这将创建 PixBuf
对象拥有的数据的副本。您可以通过在堆上分配数据并使用 create_from_data
的 const SlotDestroyData& destroy_slot
参数在 PixBuf
被销毁时删除它来避免复制。
- 我正在尝试在 window 中显示图像。
- 我将 C++ 与 Gtkmm 和 Gdkmm 库一起使用。
- 我从磁盘读取图像并创建 Gdk::Pixbuf
- 然后我将它显示在一个小部件中。这是我在屏幕上看到的内容:
- 实际图像应该是这样的:
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
指向垃圾数据。
最简单的解决方法是在 return 时复制 Pixbuf
:
return Pixbuf_from_data.copy()
这将创建 PixBuf
对象拥有的数据的副本。您可以通过在堆上分配数据并使用 create_from_data
的 const SlotDestroyData& destroy_slot
参数在 PixBuf
被销毁时删除它来避免复制。