python – 你能用Cython创建一个PIL图像而不用冗余复制内存吗?

我正在使用Cython从USB摄像头抓取图像并将其转换为返回给调用者的PIL图像.

图像的数据位于由图像抓取功能返回的结构的“convert_buffer”成员指向的字符数组中:

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

现在,我这样做把它变成PIL图像:

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)

将数据转换为python字符串的过程需要2ms才能听起来像是零复制事件.是否可以通过相机API提供的char *图像数据指针来获取PIL来创建我的图像?

最佳答案
从PIL 1.1.4开始,Image.frombuffer方法支持零拷贝:

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

问题是您的相机数据似乎是24位RGB,其中PIL需要32位RGBA / RGBX.你能控制来自相机API的像素格式吗?

如果没有,使用Image.frombuffer仍然有一个优势,因为它将接受缓冲区,而不是要求您从像素数据构建python字符串.

编辑:查看frombuffer的源代码,它是fromstring的一个光包装器,零拷贝需要Image._MAPMODES列表中的像素格式(即RGBX).至少,您必须将RGB数据复制/转换为RGBX缓冲区,以获得零拷贝兼容的像素格式.

我没有更好的方法将原始字节输入PIL,但这里有一些有趣的参考:

> Cython automatic type conversions
> Efficient indexing of objects supporting the Python buffer interface(适用于numpy / PIL)
> Converting malloc’ed buffers from C to Python without copy using Cython?
> PyMemoryView_FromMemory (python 3.3)

转载注明原文:python – 你能用Cython创建一个PIL图像而不用冗余复制内存吗? - 代码日志