将SWIG代理对象作为输入传递给PIL.Image.frombuffer

时间:2012-01-11 15:25:13

标签: python buffer python-imaging-library swig python-c-api

我正在使用carrays.i中定义的SWIG array_class宏来创建一个无符号的char缓冲区,它可以发送到我的项目的c ++端,用于处理图片拍摄。这样工作正常 - 缓冲区在相机触发后填充宽度数据,我可以使用python中的[]取消引用缓冲区以查看它包含的内容。我现在想要使用Image.frombuffer

从该缓冲区创建PIL图像
Image.frombuffer(mode, size, data) => image

(PIL 1.1.4中的新内容)。使用标准的“原始”解码器,从字符串或缓冲区对象中的像素数据创建图像内存。

但是我收到一条错误消息,告诉我我提供的SWIG对象不是python缓冲区:

  

文件“/usr/lib/python2.7/dist-packages/PIL/Image.py”,第1853行,inbuffer
  core.map_buffer(data,size,decoder_name,None,0,args)
  TypeError:期望的字符串或缓冲区

如何使SWIG对象的代理与Image.frombuffer期望的缓冲区类型兼容?

1 个答案:

答案 0 :(得分:0)

如果您可以处理强制SWIG缓冲区的签名,则可以直接创建PIL ImagingMemoryInstance。在libImaging/Imaging.h,你会发现:

struct ImagingMemoryInstance {

    /* Format */
    char mode[4+1]; /* Band names ("1", "L", "P", "RGB", "RGBA", "CMYK") */
    int type;       /* Data type (IMAGING_TYPE_*) */
    int depth;      /* Depth (ignored in this version) */
    int bands;      /* Number of bands (1, 2, 3, or 4) */
    int xsize;      /* Image dimension. */
    int ysize;

    /* Colour palette (for "P" images only) */
    ImagingPalette palette;

    /* Data pointers */
    UINT8 **image8; /* Set for 8-bit images (pixelsize=1). */
    INT32 **image32;    /* Set for 32-bit images (pixelsize=4). */

    /* Internals */
    char **image;   /* Actual raster data. */
    char *block;    /* Set if data is allocated in a single block. */

    int pixelsize;  /* Size of a pixel, in bytes (1, 2 or 4) */
    int linesize;   /* Size of a line, in bytes (xsize * pixelsize) */

    /* Virtual methods */
    void (*destroy)(Imaging im);
};

... ImagingMemoryInstance *是Imaging的typedef,这是你在整个PIL C扩展源中无处不在的基本结构。 Don't take my word for it, have a look - 就API源而言,PIL代码库非常清晰且非常一致。

正如@maxy指出的那样,您也可以轻松创建NumPy数组结构(如果不是更容易) - 但是当NumPy C API与Guido的个人剧本一样稳定时,我个人发现一个库 - 在这些情况下,源依赖就足够了。