Can you create a PIL image with Cython without redundant copying of memory?

I use Cython to capture images from a USB camera and convert them to a PIL image, which is returned to the caller.

The data for the image is in the character array pointed to by the "convert_buffer" member of the structure returned by the image capture function:

struct FlyCaptureImage: /// stuff char * convert_buffer /// more stuff 

Now I am doing this to turn it into a PIL image:

 cdef unsigned char *convert_buffer cdef Py_ssize_t byte_length cdef bytes py_string // get the number of bytes into a Py_ssize_t type byte_length = count // slice the char array so it looks like a Python str type py_string = convert_buffer[:byte_length] // create the PIL image from the python string pil_image = PILImage.fromstring('RGB', (width, height), py_string) 

This procedure for converting data to a python string takes 2 ms to make it sound like it could be a zero copy event. Is it possible to get a PIL to create my image only from the char * image data pointer that the camera API provided?

+4
source share
2 answers

As in PIL 1.1.4, the Image.frombuffer method supports a null copy:

Creates an image memory from pixel data in a string or buffer using a standard raw decoder. For some modes, the image memory will exchange memory with the original buffer (this means that changes to the original buffer object are reflected in the image). Not all modes can exchange memory; Supported modes include “L,” “RGBX,” “RGBA,” and “CMYK.”

The problem is that your camera data looks like 24-bit RGB, where PIL wants 32-bit RGBA / RGBX. Can you control the pixel format coming from the camera API?

If not, there may still be an advantage in using Image.frombuffer , as it will accept buffer instead of requiring you to build a python string from the pixel data.

Edit: looking at the source for frombuffer , this is a light wrapper on fromstring , and for a zero copy, the pixel format in the Image._MAPMODES (i.e. RGBX) list is Image._MAPMODES . At a minimum, you will need to copy / convert the RGB data to the RGBX buffer to get a pixel format compatible with zero copy.

I have no better way to get raw bytes in PIL, but here are some interesting links:

+2
source

Perhaps the way to build manually for a Python String or array.array Object is to use the C structure for it and point the buffer to your data. Since I do not need this at all, I did not go so far as to write code for it.

Just checked - it is impossible with strings - a strong body should be highlighted in one part with the headers of string objects (there is no pointer to another piece of memory).

0
source

All Articles