C++ Gdk pixbuf从内存加载图像
使用GTK+3.6,我希望显示内存缓冲区中的图像,而不是磁盘上的文件。我有一个带有图像数据的C++ Gdk pixbuf从内存加载图像,c++,image-processing,gtk,jpeg,gdkpixbuf,C++,Image Processing,Gtk,Jpeg,Gdkpixbuf,使用GTK+3.6,我希望显示内存缓冲区中的图像,而不是磁盘上的文件。我有一个带有图像数据的const char*data,我正试图从中创建一个GTK图像。 到目前为止,我已经尝试了两种我认为可行的方法。两者都使用GdkPixbuf,因此要求图像数据为guchar*(unsigned char*) 根据这一要求,我必须转换数据: guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data)); 20
const char*data
,我正试图从中创建一个GTK图像。
到目前为止,我已经尝试了两种我认为可行的方法。两者都使用GdkPixbuf,因此要求图像数据为guchar*(unsigned char*)
根据这一要求,我必须转换数据:
guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data));
2013年1月3日编辑:
已从写入函数中删除步幅参数-打印错误
Cairo曲面也不起作用。显示黑屏和噪音
将数据写入文件foo.jpg
,是的,我得到了一个正常工作的图像文件。终端中的文件
命令确认它是一个JPEG图像,通过一个简单的代码块,我从foo.jpg创建了一个GdkPixbuf,以检查它的行步长值,它与我传递给上述函数的值相匹配
图像数据是否因演员阵容而损坏,如果损坏,我如何解决?我在const char*
中获取图像数据。我已经看过QtPixmap,它还加载无符号字符*
我需要使用单独的图书馆吗?(libjpeg?)
我已经安装了libgtk3 dev
谢谢大家! 2012年1月3日更新:
下面是一个简单的工作应用程序,它在附近加载一个“test.jpg”文件(文件大小必须小于100000字节)
#包括
#包括
#包括
销毁时无效(GtkWidget*widget G_GNUC_未使用,gpointer user_数据G_GNUC_未使用)
{
gtk_main_quit();
}
int main(int argc,char*argv[])
{
文件*f;
guint8缓冲液[100000];
gsize长度;
GdkPixbufLoader*装载机;
GdkPixbuf*pixbuf;
GtkWidget*窗口;
GtkWidget*图像;
gtk_init(&argc,&argv);
f=fopen(“test.jpg”、“r”);
长度=fread(缓冲区,1,sizeof(缓冲区),f);
fclose(f);
loader=gdk_pixbuf_loader_new();
gdk_pixbuf_loader_write(加载器、缓冲区、长度、NULL);
pixbuf=gdk_pixbuf_loader_get_pixbuf(loader);
窗口=gtk_窗口_新建(gtk_窗口_顶层);
image=gtk_image_new_from_pixbuf(pixbuf);
gtk_容器添加(gtk_容器(窗口),图像);
gtk_小部件_全部显示(gtk_小部件(窗口));
g_信号连接(窗口,“销毁”,g_回调(on_销毁),空);
gtk_main();
返回0;
}
原始答案:
这里的char*
或unsigned char*
没有什么重要性
将仅读取带alpha通道(RGBA)或不带alpha通道(RGB)的未压缩RGB数据(支持的唯一颜色空间是GDK_colorspace_RGB)。难怪传递它JPEG会失败
调用gdk\u pixbuf\u loader\u write
看起来是一个更好的选择,但我们需要一些代码来了解您可能会做错什么。但是,通过在shell中运行gdk-pixbuf-query-loaders
命令并验证JPEG是否存在,检查您是否安装了用于jpg的pixbuf-loader。我运行了gdk-pixbuf-query-loaders
并安装了JPEG。此外,我将编辑问题以包含一些代码。为什么不将gdk_pixbuf_new_from_stream与GMemoryInputStream一起使用?不幸的是,我得到了“无法识别的图像文件格式”。再说一次,如果我只是将相同的数据流写入一个文件,它会生成一个正常工作的.jpg图像。使用gdk_pixbuf_loader_write在完整的缓冲区上工作得非常好。您的问题是您的“步幅”参数不在原型中。删除它对我有效。我添加了我的工作示例应用程序。如果它不适用于您的图像,请添加一些错误检查,因为这可能是该图像特有的问题。
guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data));
int stride = ((1056 * 32 + 31) & ~31)/8;
GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
GError *error = NULL;
if(!gdk_pixbuf_loader_write(loader, gudata, data_size, &error)
{
printf("Error:\n%s\n", error->message);
}
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
void on_destroy (GtkWidget *widget G_GNUC_UNUSED, gpointer user_data G_GNUC_UNUSED)
{
gtk_main_quit ();
}
int main (int argc, char *argv[])
{
FILE *f;
guint8 buffer[100000];
gsize length;
GdkPixbufLoader *loader;
GdkPixbuf *pixbuf;
GtkWidget *window;
GtkWidget *image;
gtk_init (&argc, &argv);
f = fopen ("test.jpg", "r");
length = fread (buffer, 1, sizeof(buffer), f);
fclose (f);
loader = gdk_pixbuf_loader_new ();
gdk_pixbuf_loader_write (loader, buffer, length, NULL);
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
image = gtk_image_new_from_pixbuf (pixbuf);
gtk_container_add (GTK_CONTAINER (window), image);
gtk_widget_show_all (GTK_WIDGET (window));
g_signal_connect (window, "destroy", G_CALLBACK(on_destroy), NULL);
gtk_main ();
return 0;
}