2010-05-29 42 views
5

我有代碼,需要一個PIL圖像並將其轉換爲一個ctypes陣列傳遞出一個C函數:有效地轉換字符串(或元組)到ctypes的陣列

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) 

但是我處理與大的圖像,並解開許多項目成函數參數似乎是明顯緩慢。爲了獲得合理的加速,我可以做的最簡單的事情是什麼?

我只是轉換爲一個元組作爲中間步驟,所以如果沒有必要,所有更好。

+0

有還有'(ctypes.c_int * n).from_buffer',你可以使用字符串。我仍然試圖找到如何使用它,而不需要立即將PIL'Image'轉換爲字符串。 – Kos 2012-12-12 10:20:26

回答

7

您可以先建立一個未初始化數組:

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的返回值是你不關心的地址,所以我通過將其分配給「單下劃線」(按照慣例意思是「我不在乎這個」)來「吞噬」它;-)。

編輯:如@Mu心靈在評論中指出,後者的片段可以有效簡化使用ctypes.memmove而不需要去平臺相關揪出clib:只是做

_ = ctypes.memmove(pixarray, im.tostring(), w_px * h_px * 4) 
+3

看起來像ctypes.memmove以平臺無關的方式做同樣的事情:ctypes.memmove(pixarray,im.tostring(),w_px * h_px * 4) – 2010-05-29 16:39:59

+0

@Mu,優秀,+1和謝謝!讓我相應地編輯答案。 – 2010-05-29 16:42:38

+0

糟糕,看起來像輸出有字節序問題。有什麼建議麼? – 2010-05-30 13:07:22

相關問題