[Image-SIG] Comparison of PIL and GD speed for setting pixels through python

Christopher Barker Chris.Barker at noaa.gov
Mon Feb 5 19:28:13 CET 2007

John Barratt wrote:
> I haven't tried it, but did originally think of adding it to the list of 
> things tested.  Given this specific example though, where the idea is 
> that a specific method or piece of code is needed to be run for every 
> pixel (not that it actually is in this abstract example), I would think 
> that unless that specific code can be called from, and done in C, that 
> it would perform similarly to the Image.load method.  This is because I 
> am assuming the cost of accessing the raw data from Image.load to be 
> similar to that of accessing an array type in numpy.  Having said all 
> that though, I'll have a look at adding it to the mix...

Quite true. In fact, your tests make it look like accessing individual 
pixels in numpy is pretty darn slow. I'm guessing that that's because 
numpy may be creating a numpy scalar object with every pixel access.

> I think where PIL & numpy would excel is where you have a cases of a 
> number of images with calculations required that could be easily 
> represented as array operations.  The examples I am thinking of don't 
> lend themselves to this sort of solution.

Also true -- but are you sure you couldn't do your pixel-specific 
calculations as array operations?

By the way, you really want to be using numpy 1.0.1, not numpy 0.9.8, 
numpy was undergoing a lot of flux before 1.0 came out.

Also, it looks like your code wouldn't work anyway:

data = numpy.resize(numpy.array(0),outputSize)
     for x in range(outputSize[0]):
         for y in range(outputSize[1]):
             data[x,y] = colourI

This creates a 2-d array of 32bit integers, which isn't going to match 
an RBG array. You'd need to either use RGBA, or use an WxHx3 array of bytes:

data = numpy.zeros(outputSize[0], outputSize[1], 3, dtype=numpy.ubyte)

However, that would only make it slower! I am a bit surprised that it is 
as slow as that.

John Barratt wrote:
>> You can also access raw PIL image data via C, so your top line,
>> "ctypes,c,GD raw" should be just as applicable to PIL as GD.  Or is
>> there some reason this is not so?  From memory, you'd pry open the
>> im.im object, and use something like im->image32[y][x] to access each
>> pixel.
> Ahhh, that is the sort of thing I was wanting to do with PIL, I just 
> didn't know how,

There is a movement afoot (mostly us numpy folks) to get a basic n-d 
array object into the standard Python library. The goal is that all 
packages that need an nd-array of data (such as PIL, etc) could use the 
same thing, and then they'd all have the same C API for accessing the 
data -- this looks like another good argument for that!

> The idea is that each pixel requires some relatively complex 
> piece of code to calculate each value, and one that can't be obtained by 
> simple array/image operations that work on the whole image.

careful here -- if your "relatively complex" piece of code takes 
substantially longer than the pixel setting, then all this work is for 
naught -- though we're all learning something from it!

by the way, numpy can do more than "simple array" operations -- so it 
still may help.


Christopher Barker, Ph.D.

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov

More information about the Image-SIG mailing list