эффективно преобразуйте строку (или кортеж) к массиву ctypes

У меня есть код, который берет изображение PIL и преобразовывает его в массив ctypes, чтобы упасть в обморок к функции C:

w_px, h_px = img.size
pixels = struct.unpack('%dI'%(w_px*h_px), img.convert('RGBA').tostring())
pixels_array = (ctypes.c_int * len(pixels))(*pixels)

Но я имею дело с большими изображениями и распаковываю это, много объектов в аргументы функции, кажется, являются заметно медленными. Какова самая простая вещь, которую я могу сделать для получения разумного ускорения?

Я только преобразовываю в кортеж как промежуточный шаг, поэтому если это является ненужным, тем лучше.

5
задан Mu Mind 29 May 2010 в 15:27
поделиться

1 ответ

Вы можете сначала построить неинициализированный массив:

pixarray = (ctypes.c_int * (w_px * h_px))()

,а затем скопировать в него содержимое изображения:

# dylib in MacOSX, cdll.wincrt in Win, libc.so.? in Unix, ...
clib = ctypes.CDLL('libc.dylib')

_ = clib.memcpy(pixarray, im.tostring(), w_px * h_px * 4)

Возвращаемое значение memcpy — это адрес, который вас не волнует, поэтому я «проглотил» его, присвоив ему имя «single underscore» (что по соглашению означает «Мне все равно это»;

Edit: как указывает @Mu Mind в комментарии, последний фрагмент можно с пользой упростить для использования ctypes.memmove без необходимости переходить на платформозависимый, чтобы найти clib: просто сделайте

_ = ctypes.memmove(pixarray, im.tostring(), w_px * h_px * 4)
7
ответ дан 14 December 2019 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: