2009-11-10 3 views
1

EDIT: После повторного чтения моего первоначального вопроса я понял очень быстро, что он был очень плохо сформулирован, неоднозначен и слишком запутан, чтобы когда-либо получить достойный ответ. Это то, что я получаю для того, чтобы срочно решить вопрос в конце обеденного перерыва. Надеюсь, это будет яснее:Создание PyBuffer из C-структуры

Я пытаюсь открыть простую структуру C для Python (3.x) в качестве PyBuffer, чтобы я мог извлечь из нее MemoryView. Структура Я хочу выставить похожа на это:

struct ImageBuffer { 
    void* bytes; 
    int row_count; 
    int bytes_per_row; 
}; 

и это мое желание, чтобы автор сценария для доступа к данным, как так:

img_buffer = img.get_buffer() 
img_buffer[1::4] = 255 # Set every Red component to full intensity 

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

У кого-нибудь есть совет по этому вопросу?

ответ

1

Набор методов для реализации, так что ваш тип расширения поддерживает протокол буфера описано здесь: http://docs.python.org/3.1/c-api/typeobj.html#buffer-object-structures

Я признаю, что документация довольно грубо, так что лучший совет, который я могу дать, чтобы начать с существующей реализация API-интерфейса буфера по типу C, например bytesobject.c или bytearrayobject.c, в официальном исходном коде Python.

Однако обратите внимание, что протокол буфера не дает доступа к высокоуровневым нотациям, таким как цитируемый вами: img_buffer[1::4] = 255 не будет работать с объектом memoryview.

Редактировать: Точнее, memoryviews поддерживает некоторые виды назначений slice, но не все из них. Кроме того, они недостаточно «умны», чтобы понять, что назначение 255 срезу означает, что вы хотите, чтобы значение байта повторялось. Пример:

 
>>> b = bytearray(b"abcd") 
>>> m = memoryview(b) 
>>> m[0:2] = b"xy" 
>>> b 
bytearray(b'xycd') 
>>> m[0:2] = 255 
Traceback (most recent call last): 
    File "", line 1, in 
TypeError: 'int' does not support the buffer interface 
>>> m[0:2] = b"x" 
Traceback (most recent call last): 
    File "", line 1, in 
ValueError: cannot modify size of memoryview object 
>>> m[0::2] = b"xy" 
Traceback (most recent call last): 
    File "", line 1, in 
NotImplementedError 
+0

Действительно? Memoryviews не делают нарезки? Я думал, что это должно быть большой выгодой от их использования. По крайней мере, они поддерживают базовое индексирование? Все, что я пытаюсь разоблачить эту память, - позволить разработчикам Python манипулировать данными изображения на уровне байтов, и если они не могут выполнять базовую индексацию или нарезку, то этот метод бесполезен для меня. – Toji

+0

См. Отредактированную версию выше. –

+0

А, спасибо за разъяснение. Это больше соответствует тому, что я думал. Мне придется поиграть с этим и посмотреть, смогу ли я найти хороший способ добиться того, чего хочу. Еще раз спасибо! – Toji

Смежные вопросы