使用PIL.Image和ctypes进行像素处理 [英] Pixel manipulation with PIL.Image and ctypes
问题描述
我有一个C函数,可以对8位RGB值的原始2D数组进行一些像素处理.我在c_ubyte
数组中得到响应.我的代码大致如下:
I have a C function that does some pixel manipulation on a raw 2D array of 8 bit RGB values. I get the response in a c_ubyte
array. 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))
在这一点上,我想使用PIL将图像写入文件.我目前使用以下代码将字节数据转换为图像数据:
At this point I'd like to use PIL to write the image to file. 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)
这有效,但对我来说似乎效率很低.在2.2GHz Core i7上获取592x336图像需要125毫秒.当Image可能直接从数组中获取数据时,遍历整个数组并执行此荒谬的字符串联接似乎很愚蠢.
This works but seems awfully inefficient to me. It takes 125ms for a 592x336 image on a 2.2GHz Core i7. 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.
我尝试寻找将c_ubyte
数组转换为字符串的方法,或者可能使用Image.frombuffer
而不是Image.fromstring
,但是无法实现此目的.
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.
推荐答案
我不是PIL用户,但是通常,frombuffer方法是为此类工作而设计的:
I am not a PIL user, but usually, the frombuffer methods are designed for this kind of job:
您是否已经测试过Image.frombuffer?
Have you tested Image.frombuffer?
http://effbot.org/imagingbook/image.htm
显然,有时候解决方案就在我们的鼻子下面:
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)
顺便说一下,使用frombuffer
的简写形式:
By the way, using the shorthand form of frombuffer
:
im = Image.frombuffer('RGB', (img.width, img.height), buff)
生成一张颠倒的图片.走吧...
generates an upside-down picture. Go figure...
这篇关于使用PIL.Image和ctypes进行像素处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!