简体   繁体   English

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

[英]Pixel manipulation with PIL.Image and ctypes

I have a C function that does some pixel manipulation on a raw 2D array of 8 bit RGB values. 我有一个C函数,它对8位RGB值的原始2D数组进行一些像素处理。 I get the response in a c_ubyte array. 我在c_ubyte数组中得到响应。 My code looks roughly like this: 我的代码看起来大致如下:

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

At this point I'd like to use PIL to write the image to file. 此时我想使用PIL将图像写入文件。 I currently use the following code to convert the byte data to image data: 我目前使用以下代码将字节数据转换为图像数据:

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)

This works but seems awfully inefficient to me. 这有效,但对我来说效率非常低。 It takes 125ms for a 592x336 image on a 2.2GHz Core i7. 在2.2GHz Core i7上,592x336图像需要125ms。 It seems rather silly to iterate over the entire array and do this ridiculous string join when Image could probably grab directly from the array. 当Image可能直接从数组中获取时,迭代整个数组并执行这种荒谬的字符串连接似乎相当愚蠢。

I tried looking for ways to cast the c_ubyte array to a string or maybe use Image.frombuffer instead of Image.fromstring but couldn't make this work. 我试图找到将c_ubyte数组转换为字符串的方法,或者可能使用Image.frombuffer而不是Image.fromstring但无法使其工作。

I am not a PIL user, but usually, the frombuffer methods are designed for this kind of job: 我不是PIL用户,但通常,frombuffer方法是为这种工作而设计的:

Have you tested Image.frombuffer? 你测试了Image.frombuffer吗?

http://effbot.org/imagingbook/image.htm http://effbot.org/imagingbook/image.htm

edit: 编辑:

Apparently sometime the solution is right under our noses: 显然有时候解决方案就在我们的鼻子底下:

im = Image.frombuffer('RGB', (img.width, img.height), buff, 'raw', 'RGB', 0, 1)
im.save(filename)

By the way, using the shorthand form of frombuffer : 顺便说一句,使用frombuffer的简写形式:

im = Image.frombuffer('RGB', (img.width, img.height), buff)

generates an upside-down picture. 产生一个倒置的图片。 Go figure... 去搞清楚...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM