Fri, 05 Jun 2009 22:57:39 -0000
eng, pdo, ruby, tips

Including inline images in Ruby GTK2

I'm making a simple application and I'd like to keep it self-contained into a single file; however, I'd like to use some custom icons in it.

I tried storing a pixbuf in a string::

ICON = <<EOT
/* XPM */
[...]
};
EOT

icon = Gdk::Pixbuf.new ICON

but it tried to open a file called "/* XPM */\n....".

I tried with an array::

icon = Gdk::Pixbuf.new ICON.split("\n")

But I kept getting GdkPixbuf-WARNING **:Inline XPM data is broken: Invalid XPM header. Note that trying to write that data to a file and loading the file, worked.

This worked:

icon = Gdk::Pixbuf.new "pippo.xpm"

This didn't::

tmp = IO.readlines "pippo.xpm"
icon = Gdk::Pixbuf.new tmp

I finally managed using csource:

1. gdk-pixbuf-csource --raw --name=antani image.png > /tmp/antani

2. insert /tmp/antani in the Ruby source code, strip away the comments, concat the various strings:

ICON = ""+
  "GdkP"+
  "\0\0\4\30"+
  "\1\1\0\2"+
  "\0\0\0@"+
  "\0\0\0\20"+
  "\0\0\0\20"+
  "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"+
[...]

3. load the data with icon = Gdk::Pixbuf.new ICON.unpack("C*"), true

A possible improvement could be using --rle in gdk-pixbuf-csource: raw is good for avoiding to copy the image data, but I don't feel comfortable in doing it since the image data is an integer array temporarily generated by unpack.

As usual, if you know of better ways please send me a mail and I'll update the blog entry.