2010-05-29 14 views
5

bende kod ctypes dize (veya tuple) dönüştürmek:verimli bir C işlevi geçmek için dizi bir PIL görüntü alır ve bir ctypes diziye dönüştürür

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) 

Ama uğraşıyorum büyük resimlerle ve bu birçok öğeyi işlev argümanlarına açarak fark edilir derecede yavaş görünüyor. Makul bir hızlanma elde etmek için yapabileceğim en basit şey nedir?

Yalnızca bir ara adım olarak bir tuple dönüştürüyorum, bu yüzden gereksiz ise, daha iyisi.

+0

var yapın: @Mu Zihin yorumunda işaret ettiği gibi, son fragman yararlı clib ortaya çıkarmak için platforma bağımlı gitmeye gerek kalmadan ctypes.memmove kullanmak basitleştirilmiş olabilir Ayrıca bir string ile kullanabileceğiniz (ctypes.c_int * n) .from_buffer'. Hala PIL 'Image'ı bir dizeye dönüştürme adımı olmadan kullanmayı nasıl kullanmaya çalışıyorum. – Kos

cevap

7

Önce başlatılmamış dizi inşa edebilirsiniz:

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

ve sonra içine resmin içeriğini kopyalamak: memcpy

# 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) 

dönüş değeri umurumda değil bir adres, bu yüzden “tek altçizgi” olarak adlandırarak onu “yutturdum” (ki bu konuyu "bunun hakkında umursamıyorum" ;-)).

Düzenleme: sadece

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

Görünüşe göre ctypes.memmove aynı şeyi platformdan bağımsız bir şekilde yapar: ctypes.memmove (pixarray, im.tostring(), w_px * h_px * 4) –

+0

@Mu, mükemmel, +1 ve teşekkürler! Cevabını buna göre düzenlememe izin verin. –

+0

Oops, çıktıda endianness problemleri var gibi görünüyor. Baska öneri? –

İlgili konular