2011-06-16 75 views
3

我有一个C函数,它可以对8位RGB值的原始二维数组执行一些像素操作。我在c_ubyte阵列中得到响应。我的代码看起来大致是这样的:使用PIL.Image和ctypes进行像素操作

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) 

这工作,但似乎非常低效的我。 2.2GHz Core i7上的592x336图像需要125ms。似乎相当愚蠢的迭代整个数组,并做这个荒谬的字符串连接时,图像可能可能直接从数组中抓取。

我试图寻找方法将c_ubyte数组转换为字符串,或者可能使用Image.frombuffer而不是Image.fromstring,但无法实现此功能。

回答

2

我不是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) 

生成颠倒的图片即去图...