我正在使用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来创建我的图像?
答案 0 :(得分:2)
从PIL 1.1.4开始,Image.frombuffer
方法支持零拷贝:
从字符串或缓冲区对象中的像素数据创建图像内存, 使用标准的“原始”解码器。对于某些模式,图像存储器 将与原始缓冲区共享内存(这意味着更改为 原始缓冲区对象反映在图像中)。并非所有模式 可以分享记忆;支持的模式包括“L”,“RGBX”,“RGBA”和 “CMYK”。
问题是您的相机数据似乎是24位RGB,其中PIL需要32位RGBA / RGBX。你能控制来自相机API的像素格式吗?
如果没有,使用 Image.frombuffer
仍然有一个优势,因为它会接受buffer
而不是要求你从像素数据构建一个python字符串。
编辑:查看frombuffer
的来源,它是fromstring
上的光包装,零拷贝需要Image._MAPMODES
列表中的像素格式(即RGBX)。至少,您必须将RGB数据复制/转换为RGBX缓冲区,以获得零拷贝兼容的像素格式。
我没有更好的方法将原始字节输入PIL,但这里有一些有趣的参考:
答案 1 :(得分:0)
也许,要做的就是手动组装Python String或array.array对象 - 使用C结构,并将缓冲区指向您的数据。因为我根本不需要它,所以我没有为它编写代码。
刚检查过它 - 字符串是不可能的 - strign体必须与字符串 - 对象标题一起分配(没有指向另一块内存的指针)。