【问题标题】:What is the preferred approach to display a Magick++ Image in a GTK+3 application?在 GTK+3 应用程序中显示 Magick++ 图像的首选方法是什么?
【发布时间】:2018-08-10 12:28:44
【问题描述】:

我正在开发一个用于 Linux 的 C++ 图像查看器,它是使用 GTK+3 (gtkmm) 创建的用于 GUI 和 Magick++ 用于图像处理。我的目标是支持尽可能多的图像文件格式,包括动画 GIF。

获取 Magick++ 图像并在 GTK+3 小部件中绘制它以使其适用于(几乎)任何图像文件格式的最佳方法是什么?

【问题讨论】:

    标签: c++ gtk gtk3 magick++ gtkmm3


    【解决方案1】:

    获取 Magick++ 图像并在 GTK+3 小部件中绘制它以使其适用于(几乎)任何图像文件格式的最佳方法是什么?

    只要 ImageMagick 有格式委托,你应该可以绘制 GtkWidget 图像。

    image = Gtk::manage(new Gtk::Image());
    // Load image into ImageMagick
    Magick::Image img("wizard:");
    /// Calculate how much memory to allocate
    size_t to_allocate = img.columns() * img.rows() * 3;
    // Create a buffer
    guint8 * buffer = new guint8[to_allocate];
    // Write pixel data to buffer.
    img.write(0, 0, img.columns(), img.rows(), "RGB", Magick::CharPixel, buffer);
    // Build a Pixbuf from pixel data in memory.
    Glib::RefPtr<Gdk::Pixbuf> pBuff = Gdk::Pixbuf::create_from_data(buffer, Gdk::COLORSPACE_RGB, false, 8, img.columns(), img.rows(), img.columns()*3 );
    // Set GtkImage from Pixbuf
    image->set(pBuff);
    

    混合 C/C++ 方法的原始答案。

    使用以下 Magick++ 方法签名将像素数据导出到内存中。

    Magick::Image.write(const ssize_t x_,
                        const ssize_t y_,
                        const size_t columns_,
                        const size_t rows_,
                        const std::string &map_,           //<= Usually "RGB"
                        const StorageType type_,           //<= Usually CharType
                        void *pixels_)                     //<= Be sure to allocate _all_ the memory required (size of storage * number of channels * columns * rows)
    

    使用以下 GTK 方法从上面导出的像素创建 GdkPixBuf。

    GdkPixbuf *
    gdk_pixbuf_new_from_bytes (GBytes *data,               //<= Same as pixels_.
                               GdkColorspace colorspace,   //<= Match colorspace channels from map_.
                               gboolean has_alpha,         //<= Usually no.
                               int bits_per_sample,        //<= Match StorageType bits
                               int width,                  //<= Same as columns_.
                               int height,                 //<= Same as rows_.
                               int rowstride);             //<= size of data-type * number of channel * width.
    

    最后,使用以下方法从 PixBuf 构建 GtkImage。

    GtkWidget * gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf);
    

    【讨论】:

    • 这些是 C API,OP 使用的是 C++。
    • 捂脸! @liberforce 是对的。我会用例子更新答案。
    • 感谢您的回答和示例。只是为了记录,对于具有 alpha 通道的图像,您可以使用 Magick++ Image 的 matte() 属性来检查图像是否具有 alpha 通道,然后使用“RGBA”编写并创建具有 has_alpha 参数设置为 true 的 Pixbuf .这似乎也适用于没有 alpha 的图像,但当然你必须为额外的通道增加额外的内存。不知道有没有其他(缺点)优点。
    • ImageMagick-7 没有弃用遮罩?
    • @emcconville 您对此似乎是正确的。现在它似乎被称为 alpha()。
    【解决方案2】:

    我想@emcconville 适合 ImageMagick 部分,因为我对此一无所知。

    不过,对于 GTKmm 部分,您需要坚持使用 C++ API,因此请使用 Gdk::Pixbuf::create_from_data 从 ImageMagick 读取图像。

    此外,在创建图像查看器时,您需要更改Gtk::Image 显示的图像。因此,在启动时只需使用由Gtk::Image::Image(或Glade 和Gtk::Builder)创建的空Gtk::Image,然后使用Gtk::Image::set 更改其中显示的图像,并将其传递给您的pixbuf。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 2014-03-31
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 2011-08-09
      相关资源
      最近更新 更多