我有一个库,它接受一个非常简单的C图像结构:
// Represents a one-channel 8-bit image
typedef struct simple_image_t {
uint32 rows;
uint32 cols;
uint8 *imgdata;
} simple_image;
我没有创建这个库,也没有创建这个结构,所以我不能改变它。我的责任是使用SWIG为Python封装这个库。Python包装器需要能够接收PIL图像并将其转换为这个结构。这是我目前的做法(使用SWIG %inline%
):
// Allows python to easily create and initialize this structure
simple_image* py_make_simple_image(uint32 width, uint32 height)
{
simple_image* img = new simple_image();
img->rows = height;
img->cols = width;
img->imgdata = new uint8[height * width];
return img;
}
// Allows python to set a particular pixel value
void py_set_simple_image(simple_image* img, uint32 pos, uint8 val)
{
img->imgdata[pos] = val;
}
现在来看一下Python包装器的情况:
# Make sure it's an 8-bit image
if pil_image.mode != "L":
pil_image = pil_image.convert("L")
# Create the simple image structure
(width, height) = pil_image.size
img = swig_wrapper.py_make_simple_image(width, height)
try:
# Copy the image data into the simple image structure
pos = 0
for pixel in pil_image.getdata():
swig_wrapper.py_set_simple_image(img, pos, pixel)
pos += 1
# Call some library method that accepts a simple_image*
return swig_wrapper.some_image_method(img)
finally:
# Clean up the simple image structure
swig_wrapper.py_destroy_simple_image(img)
惊人的是,这个方法确实可行,但是你可能已经猜到了,当处理相对较大的图像时,速度非常缓慢。我知道使用SWIG正确的做法是使用typemap,但这意味着要深入PIL的C API,而我目前没有时间去做。
在速度方面,我的选择是什么?有更快的方式来将PIL图像中的像素数据转换为这个简单的图像结构吗?有人已经做过这个事情,只是我的谷歌搜索技能太差了吗?还是我注定要学习PIL的内部工作呢?
谢谢。
Image
类包含一些序列化方法 -getdata
,tostring
。其中一个肯定可以被强制转换为您所需的操作。 - zdav