Effectively convert a string (or tuple) into a ctypes array

I have code that takes a PIL image and converts it to a ctypes array to pass to the C function:

w_px, h_px = img.size pixels = struct.unpack('%dI'%(w_px*h_px), img.convert('RGBA').tostring()) pixels_array = (ctypes.c_int * len(pixels))(*pixels) 

But I'm dealing with large images and unpacking, that many elements in function arguments seem noticeably slow. What is the easiest thing I can do to get reasonable acceleration?

I only convert to a tuple as an intermediate step, so if it is not needed, so much the better.

+5
python python-imaging-library ctypes
source share
1 answer

You can create an uninitialized array first:

 pixarray = (ctypes.c_int * (w_px * h_px))() 

and then copy the contents of the image into it:

 # dylib in MacOSX, cdll.wincrt in Win, libc.so.? in Unix, ... clib = ctypes.CDLL('libc.dylib') _ = clib.memcpy(pixarray, im.tostring(), w_px * h_px * 4) 

The returned memcpy value is an address that you are not interested in, so I "swallowed" it by assigning it the name "single underscore" (which by convention means "it does not concern me";).

Edit : as @Mu Mind points out in a comment, the last snippet can be usefully simplified to use ctypes.memmove without having to go to the platform for clib to hang: just do

 _ = ctypes.memmove(pixarray, im.tostring(), w_px * h_px * 4) 
+7
source share

All Articles