Передача прокси-объекта SWIG в качестве входных данных в PIL.Image.frombuffer - PullRequest
1 голос
/ 11 января 2012

Я использую макрос SWIG array_class, определенный в carrays.i, чтобы создать неподписанный буфер символов, который можно отправить на сторону c ++ моего проекта, которая обрабатывает съемку изображений. Это работает нормально - буфер заполняет данные ширины после срабатывания камеры, и я могу разыменовать буфер, используя [] из python, чтобы увидеть, что он содержит. Теперь я хочу создать изображение PIL из этого буфера, используя Image.frombuffer:

Image.frombuffer(mode, size, data) => image

(Новое в PIL 1.1.4). Создает память изображений из данных пикселей в строковом или буферном объекте, используя стандартный «сырой» декодер.

но я получаю сообщение об ошибке, сообщающее, что предоставляемый мной SWIG-объект не является буфером python:

Файл "/usr/lib/python2.7/dist-packages/PIL/Image.py", строка 1853, в frombuffer
core.map_buffer (данные, размер, имя декодера, None, 0, args)
Ошибка типа: ожидаемая строка или буфер

Как я могу сделать этот прокси объекта SWIG совместимым с типом буфера, который Image.frombuffer ожидает?

1 Ответ

0 голосов
/ 02 марта 2012

Если вы можете справиться с принудительной подписью вашего буфера 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 * имеет typedef'd to Imaging, который является базовой структурой, которую вы найдете повсеместно в источнике расширения PIL C. Не поверьте мне на слово, взгляните - что касается исходного кода API, кодовая база PIL особенно разборчива и довольно логична.

Как указывает @maxy, вы также можете создать структуру массива NumPy так же просто (если не проще) - но хотя API NumPy C так же стабилен, как и из личной книги Гвидо, я лично обнаружил, что В этих сценариях достаточно зависимости от источника.

...