GTK Custom Drawing and Saving
In one of the previous mentioned homework, I had to draw an image of a neural network on a custom widget and later save said image to file. This post was inspired by this task.
The assignment was done in Python with PyGTK. Looking at the documentation for doing custom draws, I saw that one has to use a Pixmap obtained by using an Image object and then use methods associated with the drawing context obtained from it. This works, is easy to reason about but has a small problem.
When you also want to save the image to a file you cannot use the same Pixmap. That is because GTK can only save Pixbuff content, not Pixmaps. And you cannot easily convert between one structure and the other. In fact, you cannot even use Image methods to obtain what you need: Pixbuff or Pixmap. That is because a Image has a backup structure and that backup structure can be a Pixbuff or a Pixmap (or several some others, as taken from PyGTK documentation).
After many failed attempts to do this, I’ve come across the following convoluted solution. It was found after long search through the maze of PyGTK documentation (even dropping a little to the level of GTK documentation and trying a cross-language translation) but it worked at least.
cmap = drawable.get_colormap() pbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, *drawable.get_size()) pbuf = pbuf.get_from_drawable(drawable, cmap, 0, 0, 0, 0, *drawable.get_size()) pbuf.save(fName, 'png')
After this project was finished, I’ve moved to the next which was done in Haskell. There I also had to do a custom drawing but, this time, I’ve turned to using Cairo. Much simpler and easier to reason about. And much simpler to save the images to files if needed.
Unfortunately, the PyGTK documentation seems to fail to mention this or at least give a hint to use Cairo instead of native GTK methods. But this can be fixed since we know that this project is open source.
I’ll come back later with more code related articles. In fact, I think I may start a series of articles soon.