【问题标题】:Gdk pixbuf load image from memorygdk pixbuf 从内存中加载图片
【发布时间】:2013-01-02 11:22:59
【问题描述】:

使用 GTK+ 3.6 我想显示来自内存缓冲区的图像,而不是磁盘上的文件。我有一个带有图像数据的const char *data,我正在尝试从中创建一个 GTK 图像。 到目前为止,我已经尝试了两种我认为可行的方法。两者都使用 GdkPixbuf,因此要求图像数据为guchar* (unsigned char*)

根据这个要求,我必须转换数据:

guchar *gudata = reinterpret_cast<guchar*>(const_cast<char*>(data));

然后我尝试了以下方法:

  1. 使用gdk_pixbuf_loader_write 将数据写入 GdkPixbufLoader。在这里我收到一个错误 "Unrecognized image file format" 或者如果我创建具有特定类型 (jpg) 的加载程序我收到一个错误说它不是 JPG 文件格式(它是,下面解释)。

    编辑:一些代码:

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

    编辑 2013 年 3 月 1 日: 从 write 函数中删除了 stride 参数 - 打印错误。

    开罗表面效果不佳。显示黑屏和噪音。

  2. 使用gdk_pixbuf_new_from_data 初始化pixbuf,然后图像看起来像电视噪音,这表明数据错误(并且已被投射),或者其他参数错误(图像行大步前进,但不是:))。

发生错误后,我只是尝试使用ofstream 将数据写入文件foo.jpg,是的,我得到了一个正常工作的图像文件。终端中的 file 命令确认它是 JPEG 图像,并且通过一个简单的代码块,我从该 foo.jpg 创建了一个 GdkPixbuf 以检查它的行步幅值,它与我传递给上述的值相匹配功能。

图像数据是否会因演员表而损坏,如果是,我该如何解决?我在const char* 中获取图像数据。我查看了 QtPixmap,它还加载了unsigned char*

我需要使用单独的库吗? (libjpeg?) 我已经安装了 libgtk3-dev。

谢谢!

【问题讨论】:

    标签: c++ image-processing gtk jpeg gdkpixbuf


    【解决方案1】:

    2012 年 3 月 1 日更新:

    这是一个简单的工作应用程序,它在其附近加载“test.jpg”文件(文件大小必须小于 100000 字节)。

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

    原答案:

    这里的char *unsigned char * 并不重要。

    gdk_pixbuf_new_from_data 只会读取带有 Alpha 通道 (RGBA) 或不带 Alpha 通道 (RGB) 的未压缩 RGB 数据(唯一支持的色彩空间是 GDK_COLORSPACE_RGB)。难怪通过 JPEG 会失败。

    调用gdk_pixbuf_loader_write 似乎是一个更好的选择,但我们需要一些代码来查看您可能做错了什么。但是,通过在 shell 中运行 gdk-pixbuf-query-loaders 命令并验证 JPEG 是否存在,检查您是否安装了 jpg 的 pixbuf 加载程序。

    【讨论】:

    • 我跑了gdk-pixbuf-query-loaders 并安装了JPEG。另外,我将编辑问题以包含一些代码。
    • 为什么不将 gdk_pixbuf_new_from_stream 与 GMemoryInputStream 一起使用?
    • 不幸的是,我得到“无法识别的图像文件格式”。同样,如果我只是将相同的数据流写入一个文件,它会产生一个正常工作的 .jpg 图像。
    • 好的,知道了。在整个缓冲区上使用 gdk_pixbuf_loader_write 效果很好。您的问题是您的“步幅”参数不在原型中。删除它对我有用。
    • 我添加了我的工作示例应用程序。如果它不适用于您的图像,请添加一些错误检查,因为它可能是该图像特有的问题。
    猜你喜欢
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多