[pygtk] Per pixel access to a pixbuf

BJörn Lindqvist bjourne at gmail.com
Mon Jun 26 00:30:27 WST 2006

I need to do lots of per-pixel manipulation of gdk.Pixbufs. First i
started with pure Python because it was the simplest:

pixels = pixbuf.get_pixels()
for y in range(pixbuf.get_height()):
    for x in range(pixbuf.get_width()):
        [do some manipulation with the pixel at (x, y)]
[return a new pixbuf]

But that was to slow so I tried doing the same thing with Numeric:

pixelarr = pixbuf.get_pixels_array()
for y in range(pixbuf.get_heihgt()):
    for x in range(pixbuf.get_width()):
        pixel = pixelarr[y, x]
        [do something with pixel]
        pixelarr[y, x] = pixel

But that was even slower. Element access in Numeric is really freaking
dirt slow. So now I'm trying to create a Pyrex extension module
instead to do it. Problem is that pixbuf.get_pixels() return a Python
string and therefore is immutable. In pure C, I could have written
something like:

char *pixels = gdk_pixbuf_get_pixels(pixbuf);
int width = gdk_pixbuf_get_width(pixbuf);
for (int y = 0; y < gdk_pixbuf_get_height(pixbuf); y++)
    for (int x = 0; x < width; x++)
        char *pixel = &pixels[(y * width + x) * 4];
        [ do something with pixel]

I somehow need to get to the mutable char pointer array of pixel data
so that I can manipulate my pixbuf efficiently. gdk.Pixbuf doesn't
have a method for that. So I think that I need to somehow "cast" my
Python reference to the gdk.Pixbuf to a C reference to GdkPixbuf so
that I then can call gdk_pixbuf_get_pixels() on it. How do I do it?

Thanks in advance.

mvh Björn

More information about the pygtk mailing list