views:

459

answers:

3

Hi I'm using PIL

    im = Image.open(teh_file)
    if im:
        colors = im.resize( (1,1), Image.ANTIALIAS).getpixel((0,0)) # simple way to get average color
        red = colors[0] # and so on, some operations on color data

The problem is, on a few (very few, particulary don't know why those exactly, simple jpegs) I get 'unsubscriptable object' on line "colors[0]". Tried:

if colors:

gets true and goes on.

if len(colors):

gives 'len() of unsized object'

  1. What condition should I apply not to get this exception?
  2. What's the cause of the problem?
+4  A: 

From the PIL docs:

getpixel

im.getpixel(xy) => value or tuple

Returns the pixel at the given position. If the image is a multi-layer image, this method returns a tuple.

So it seems that some of your images are multilayer, and some are single-layer.

Ignacio Vazquez-Abrams
+1  A: 

As noted in another answer, getpixel returns either a single value, or a tuple. You could check the type and do the appropriate action in the following ways:

if isinstance(colors, tuple):
    color = colors[0]
else:
    color = colors
# Do other stuff

or:

try:
    color = colors[0]
except: # Whatever the exception is - IndexError or whatever
    color = colors
# Do other stuff

The second way is probably more Pythonic.

mipadi
+2  A: 

Ok the case was, that when B&W images have no RGB band (L band), it returns an integer with the pixel color single value, not a list of rgb values. The solution is to check bands

im.getbands()

or the simpler for my needs was:

        if isinstance(colors, tuple):
            values = {'r':colors[0], 'g':colors[1], 'b':colors[2]}
        else:
            values = {'r':colors, 'g':colors, 'b':colors}
zalew
dict(zip('rgb', colors if isinstance(colors, tuple) else [colors]*3))
J.F. Sebastian