使用PIL.Image和ctypes进行像素操作

时间:2011-06-16 07:46:53

标签: python python-imaging-library ctypes

我有一个C函数,可以对8位RGB值的原始2D数组进行一些像素处理。我在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)

这有效,但对我来说似乎非常低效。在2.2GHz Core i7上,592x336图像需要125ms。当Image可能直接从数组中获取时,迭代整个数组并进行这种荒谬的字符串连接似乎相当愚蠢。

我尝试了将c_ubyte数组转换为字符串的方法,或者使用Image.frombuffer代替Image.fromstring,但无法使其正常工作。

1 个答案:

答案 0 :(得分: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)

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