Я пытаюсь выставить буфер пикселя информации (32 бит RGBA) через буферный интерфейс Python 3.x. После совсем немного играл вокруг, я был в состоянии получить эту работу следующим образом:Назначение в Python 3.x Буферы с itemsize> 1
int Image_get_buffer(PyObject* self, Py_buffer* view, int flags)
{
int img_len;
void* img_bytes;
// Do my image fetch magic
get_image_pixel_data(self, &img_bytes, &img_len);
// Let python fill my buffer
PyBuffer_FillInfo(view, self, img_bytes, img_len, 0, flags);
}
И питона я могу играть с ним, как так:
mv = memoryview(image)
print(mv[0]) # prints b'\x00'
mv[0] = b'\xFF' # set the first pixels red component to full
mx[0:4] = b'\xFF\xFF\xFF\xFF' # set the first pixel to white
И это работает прекрасно. Тем не менее, было бы здорово, если бы я мог работать с полной пиксельного значения (INT, 4 байта), а не отдельных байтов, поэтому я изменил буфер выборки следующим образом:
int Image_get_buffer(PyObject* self, Py_buffer* view, int flags)
{
int img_len;
void* img_bytes;
// Do my image fetch magic
get_image_pixel_data(self, &img_bytes, &img_len);
// Fill my buffer manually (derived from the PyBuffer_FillInfo source)
Py_INCREF(self);
view->readonly = 0;
view->obj = self;
view->buf = img_bytes;
view->itemsize = 4;
view->ndim = 1;
view->len = img_len;
view->suboffsets = NULL;
view->format = NULL;
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
view->format = "I";
view->shape = NULL;
if ((flags & PyBUF_ND) == PyBUF_ND)
{
Py_ssize_t shape[] = { (int)(img_len/4) };
view->shape = shape;
}
view->strides = NULL;
if((flags & PyBUF_STRIDED) == PyBUF_STRIDED)
{
Py_ssize_t strides[] = { 4 };
view->strides = strides;
}
return 0;
}
Это фактически возвращает данные, и я могу прочитайте его правильно, но любая попытка присвоить ему значение теперь не срабатывает!
mv = memoryview(image)
print(mv[0]) # prints b'\x00\x00\x00\x00'
mv[0] = 0xFFFFFFFF # ERROR (1)
mv[0] = b'\xFF\xFF\xFF\xFF' # ERROR! (2)
mv[0] = mv[0] # ERROR?!? (3)
В случае 1 ошибка сообщает мне, что 'int' does not support the buffer interface
, который является позором и немного запутанным (я указать, что формат буфера был «я» в конце концов), но я могу с этим справиться. В случае, если 2 и 3 вещи получить действительно странно, хотя: В обоих случаях жиме мне TypeError чтение mismatching item sizes for "my.Image" and "bytes"
(Где my.Image
, очевидно, мой тип изображения)
Это очень запутанным для меня, так как данные я переходящего в очевидно, того же размера, что и у меня из этого элемента. Кажется, что буферы просто перестают разрешать присваивание, если размер элементов больше 1. Конечно, документация для этого интерфейса действительно разрежена и просматривается через код python, на самом деле не дает примеров использования, поэтому я довольно застрял. Я пропустил некоторый фрагмент документации, в которой говорится, что «буферы становятся практически бесполезными, когда itemsize> 1», я делаю что-то неправильно, что я не вижу, или это ошибка в Python? (Тестирование против 3.1.1)
Благодарим за понимание, которое вы можете дать по этой (правда, расширенной) проблеме!
говорит: «'int' не поддерживает интерфейс буфера» или «объект не поддерживает буферный интерфейс»? –
Он явно говорит «int», точно так же, как я набрал его. – Toji
ОК, просто проверка –