python 2.6: how to modify a PIL image from C without copying forthand back


N

News123

Hi,

I created a grayscale image with PIL.

Now I would like to write a C function, which reads a;most all pixels
and will modify a few of them.


My current approach is:
- transform the image to a string()
- create a byte array huge enough to contain the resulting image
- call my c_function, which copies over the entire image in order
to modify a few pixels
How can I achieve this with the least amount of copies?


########## Python code snippet ################

im = Image.open('grayscalefile_onebyteperpixel')
wx,wy = im.size

# create a string in order to pass it to my function
# I'm afraid this involves copying so want to get rid of it
im_as_string = im.tostring()

# create a byte array in order to store my result
new_img_array = array.array('B', [0]*(wx*wy) )


# my function which should just change some pixels has
# to copy all unmodified pixels
my_extension.my_func(wx,wy,im_as_string,new_img_array)


im = Image.frombuffer('L',(wx,wy),new_img_array)
show(im2)

############ C wrapper code snippet ###############

int wx,wy;
Py_buffer img;
Py_buffer new_img;
Py_buffer table;
unsigned char *img_ptr;
unsigned char *new_img_ptr;

int ok = PyArg_ParseTuple(args,
"iis*w*",&wx,&wy,&img,&new_img);
img_ptr = (unsigned char *) img.buf;
new_img_ptr = (unsigned char *) new_img.buf;
my_func(wx,wy,img_ptr,new_img_ptr);


Thanks in advance for any suggestions to make this more efficient.


bye


N
 
Ad

Advertisements

N

News123

Hi Tim,

Tim said:
If it were me, I'd be tempted to go peek at the source code for PIL, then
pass the Image object to my C routine and poke at the innards to find the
buffer with the pixels.

Yes, this might be an option
Somehow though it didn't feel right for me to depend on internal non
documented data types, which might change between releases of PIL.

N
 
S

Stefan Behnel

News123, 03.03.2010 01:38:
I created a grayscale image with PIL.

Now I would like to write a C function, which reads a;most all pixels
and will modify a few of them.

My current approach is:
- transform the image to a string()
- create a byte array huge enough to contain the resulting image
- call my c_function, which copies over the entire image in order
to modify a few pixels
How can I achieve this with the least amount of copies?

Take a look at Cython instead, it will allow you to access PIL's image
buffer directly, instead of copying the data. It will also simplify and
speed up your C wrapper code.

Stefan
 
N

News123

Hi Stefan,

Stefan said:
News123, 03.03.2010 01:38:

Take a look at Cython instead, it will allow you to access PIL's image
buffer directly, instead of copying the data. It will also simplify and
speed up your C wrapper code.

Stefan

I don't know Cython. Having looked at the web site I'm not entirely
sure, I understood your suggestion.

Do you mean
- to stay with Python 2.6 and to implement only my extension in Cython.
This might be very attractive. If yes, can you recommend some url's /
tutorials / etc. which might help to implement a cython extension for
python2.6. which reads and modifies a pixel of a PIL image.

or do you mean
- to switch entirely from Python 2.6 to Cython. I would be reluctant to
do so, as I have already a lot of existing code. and I do not have the
time to check the entire code base for portability issues



thanks in advance


N
 
Ad

Advertisements

S

Stefan Behnel

News123, 03.03.2010 10:37:
I don't know Cython. Having looked at the web site I'm not entirely
sure, I understood your suggestion.

Do you mean
- to stay with Python 2.6 and to implement only my extension in Cython.
Absolutely.


This might be very attractive. If yes, can you recommend some url's /
tutorials / etc. which might help to implement a cython extension for
python2.6. which reads and modifies a pixel of a PIL image.

Check out the tutorial on the web site, and ask on the cython-users mailing
list about integration with PIL. I'm sure you'll get some useful examples.

Here's something closely related, although it doesn't really use PIL (but
the mechanisms are the same):

http://wiki.cython.org/examples/mandelbrot

or do you mean
- to switch entirely from Python 2.6 to Cython. I would be reluctant to
do so, as I have already a lot of existing code. and I do not have the
time to check the entire code base for portability issues

The nice thing about Cython is that you always have a normal CPython
interpreter running, so you can split your code between the interpreter and
the compiler at any level of granularity. However, the advice was really to
write your image processing algorithm in Cython, not your entire program.

Stefan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top