Пиксельные манипуляции с PIL.Image и ctypes - PullRequest
3 голосов
/ 16 июня 2011

У меня есть функция C, которая выполняет некоторые манипуляции с пикселями в необработанном двумерном массиве 8-битных значений RGB.Я получаю ответ в массиве c_ubyte.Мой код выглядит примерно так:

from ctypes import cdll, CDLL, Structure, byref, c_utype, c_uint

# get a reference to the C shared library
cdll.loadLibrary(path_to_my_c_lib)
myclib = CDLL(path_to_my_c_lib)

# define the ctypes version of the C image that would look something like:
#     struct img {
#         unsigned char data[MAX_IMAGE_SIZE];
#         unsigned int width;
#         unsigned int height;
#     }
class Img(Structure): _fiels_ = [
    ('data', c_ubyte * MAX_IMAGE_SIZE),
    ('width', c_uint),
    ('height', c_uint),
]

# create a blank image, all pixels are black
img = Image()
img.width = WIDTH
img.height = HEIGHT

# call the C function which would look like this:
#     void my_pixel_manipulation_function(struct img *)
# and would now work its magic on the data
myclib.my_pixel_manipulation_function(byref(img))

На данный момент я хотел бы использовать PIL для записи изображения в файл.В настоящее время я использую следующий код для преобразования байтовых данных в данные изображения:

from PIL import Image

s = ''.join([chr(c) for c in img.data[:(img.width*img.height*3)]])
im = Image.fromstring('RGB', (img.width, img.height), s)

# now I can...
im.save(filename)

Это работает, но мне кажется крайне неэффективным.Требуется 125 мс для изображения 592x336 на 2,2 ГГц Core i7.Кажется довольно глупым перебирать весь массив и делать это смешное объединение строк, когда Image может, вероятно, получить непосредственно из массива.

Я пытался найти способы приведения массива c_ubyte к строке или, возможно, использоватьImage.frombuffer вместо Image.fromstring, но не смог сделать эту работу.

1 Ответ

2 голосов
/ 16 июня 2011

Я не пользователь PIL, но обычно методы frombuffer предназначены для такой работы:

Вы тестировали Image.frombuffer?

http://effbot.org/imagingbook/image.htm

редактирование:

Видимо, когда-нибудь решение прямо у нас под носом:

im = Image.frombuffer('RGB', (img.width, img.height), buff, 'raw', 'RGB', 0, 1)
im.save(filename)

Кстати, используя сокращенную форму frombuffer:

im = Image.frombuffer('RGB', (img.width, img.height), buff)

создает перевернутую картинку. Пойди разберись ...

...