8
votes

I have an image/pixbuf that I want to draw into a gtk.DrawingArea and refresh frequently, so the blitting operation has to be fast. Doing it the easy way:

def __init__(self):
  self.drawing_area = gtk.DrawingArea()
  self.image = gtk.gdk.pixbuf_new_from_file("image.png")

def area_expose_cb(self, area, event):
  self.drawing_area.window.draw_pixbuf(self.gc, self.image, 0, 0, x, y)

However leads to very slow performance, likely caused by the pixbuf not being in the displays color format.

I had no success with Cairo either, as it seems limited to 24/32bit formats and doesn't have a 16bit format (FORMAT_RGB16_565 is unsupported and deprecated).

What alternatives are there to drawing pictures quickly in Gtk+?

3

3 Answers

7
votes

Try creating Pixmap that uses the same colormap as your drawing area.

dr_area.realize()
self.gc = dr_area.get_style().fg_gc[gtk.STATE_NORMAL]
img = gtk.gdk.pixbuf_new_from_file("image.png")
self.image = gtk.gdk.Pixmap(dr_area.window, img.get_width(), img.get_height())
self.image.draw_pixbuf(self.gc, img, 0, 0, 0, 0)

and drawing it to the screen using

dr_area.window.draw_drawable(self.gc, self.image, 0, 0, x, y, *self.image.get_size())
2
votes

Are you really not generating enough raw speed/throughput? Or is it just that you're seeing flickering?

If it's the latter, perhaps you should investigate double buffering for perfomring your updates instead? Basically the idea is to draw to an invisible buffer then tell the graphics card to use the new buffer.

Maybe check out this page which has some information on double buffering.

0
votes

It may be worth doing some benchmarking - if you draw with a small area is it still slow?

If it is, it may be worth asking on pygtk or gtk mailing lists...