Я использую Python, PIL и ctypes для манипулирования изображениями.Когда я взламывал вещи вместе, я использовал функцию PIL fromstring
, чтобы получить буфер пикселей из ctypes в объект PIL.Я просто перебрал массив, построив строку python.
Это работает
tx = foo.tx
tx.restype = POINTER(c_ubyte)
result = tx(...args...)
#TODO there must also be a better way to do this
pystr = ""
for i in xrange(w*h*4):
pystr += result[i]
i = Image.fromstring("RGBA", (w, h), pystr)
i.save("out.png")
Это было не красиво, но это работало.Прокомментировал с TODO и перешел.После установки начального соединения профилирование показало значительные проблемы с производительностью этого блока кода.Не удивительно, я думаю.
Это не работает
Аналогично этому вопросу: Пиксельные манипуляции с PIL.Image и ctypes , япопытка использовать frombuffer()
для более эффективного получения данных пикселей в объекте PIL:
tx = foo.tx
tx.restype = POINTER(c_ubyte)
result = tx(...args...)
i = Image.frombuffer('RGBA', (w, h), result, 'raw', 'RGBA', 0, 1)
i.save("out.png")
Несмотря на работу fromstring
, использование frombuffer
приводит к следующему исключению:
Traceback (most recent call last):
File "test.py", line 53, in <module>
i = Image.frombuffer('RGBA', (w, h), res, 'raw', 'RGBA', 0, 1)
File "/Library/Python/2.7/site-packages/PIL/Image.py", line 1853, in frombuffer
core.map_buffer(data, size, decoder_name, None, 0, args)
ValueError: buffer is not large enough
Среда
Буфер malloc
'имеет C-образный вид:
unsigned char *pixels_color = (unsigned char*)malloc((WIDTH*HEIGHT*4)*sizeof(unsigned char*));
- Буфер имеет 4 байта на пиксель для каждого изполосы RGBA.
- Mac OS X 10.7, python2.7.1, PIL 1.1.7
Редактировать
На основе eryksunКомментарий и ответ ниже, я переместил распределение буфера из malloc
в библиотеке C в Python и передал указатель в C:
tx = foo.tx
tx.restype = POINTER(c_ubyte)
pix_clr = (c_ubyte*(w*h*4))()
tx(...args..., pix_clr)
i = Image.frombuffer('RGBA', (w, h), pix_clr, 'raw', 'RGBA', 0, 1)
i.save("out.png")
Это работает, как и ожидалось.Это до сих пор не объясняет , почему PIL был недоволен выделенным для C буфером, но в любом случае это лучшая структура для управления памятью.Спасибо и ErykSun, и HYRY!