views:

808

answers:

3

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+?

+1  A: 

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.

Chris Harris
It is throughput not flickering. I am trying to do some interactive fullscreen scrolling/animtion on the OLPC, which isn't very fast to begin and has a rather large screen on top of that and it runs in 16bit.Doing the same thing in SDL works without a problem. Using a gtk.Layout and use that for the scrolling is reasonably fast to, but doing the scrolling manually by drawing to a gtk.DrawingArea (as I might want to add more effects later) is completly unusable slow.
Grumbel
+2  A: 

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())
Ivan Baldin
A: 

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...

Stuart Axon