I'm trying to locate the 'x' positions of certain pixels. Here's and example image:
http://img404.imageshack.us/img404/3418/10x.png

if I run this code it gives me the 88 'odd' pixels that I'm looking for:

from PIL import Image

i = Image.open('10x.bmp') # I save it as a bmp
for pixel in i.getdata():
    if pixel [2] > 0:
        print pixel

Now that I have the pixels, I can't figure out how to locate the 'x' positions. How is this done?

I can't seem to find a way to get the width of the image (which is a little retarded).

If you can find the width and I'm just a giant noob, then you can code it something like this:

x = 0
y = 0
for pixel in i.getdata():
    x += 1
    print x

    if x == width:
        x = 0
        y += 1

But then, being a giant noob, what do I know?

Yeah its not too hard to find the size.. There isnt a function but when you open an image it stores it in the size variable.

So

from PIL import Image

f = Image.open("10x.png")
print f.size

Hope that helps

The easiest way is to create a dictionary where the key is the (x,y) location tuple and the value is the (r,g,b) color tuple of the pixel:

#!/usr/bin/env python

# image data analysis using PIL, keep track of pixel value
# (r,g,b) and location (x,y) with a (x,y):(r,g,b) dictionary

from PIL import Image

# the french_flag test file is a 24X16 bitmap and
# has a simple blue-white-red, left to right pattern
img = Image.open("french_flag.bmp")
width, height = img.size

#print width, height

pixel_list = list(img.getdata())

# create a (x,y):(r,g,b) dictionary
# where (x,y) are the location coordinates an image point
# and (r,g,b) is the value of the pixel at that point
pixel_dict = {}
ix = 0
# rows
for y in range(height):
    # columns
    for x in range(width):
        pixel_dict[(x, y)] = pixel_list[ix]
        #print x, y, ix
        ix += 1

# testing ...
# show contents of the first row
y = 0
for x in range(width):
    print( "(%d, %d): %s"% (x, y, pixel_dict[(x, y)]) )

'''
print('-'*20)

# show contents of the dictionary sorted by (x, y) coordinates
for k, v in sorted(pixel_dict.items()):
    print k, v
'''

print('-'*20)

# get the pixel (r, g, b) value at point (x, y)
x = 1
y = 10
print(pixel_dict[(x, y)])
Comments
that's easy but very wasteful. you end up with three copies of the exact same data in memory, and for images that can be a lot.

Thanks for the replies. Sneekula, that's along the lines of what I'm after but when I run that on the image I have, it doesn't print out the B values like with the first code I posted.
My code on my image results in:
(partial list)
(77, 0, 8)
(89, 0, 8)
(41, 0, 10)
(50, 0, 7)
(42, 0, 5)
(55, 0, 9)
(112, 0, 5)
(105, 0, 9)
(113, 0, 8)
(97, 0, 6)
Which is just printing out the R,G,B where 'B' is > 0.
but running your code on my image I get:
(partial list)
(0, 0): (0, 0, 0)
(1, 0): (1, 0, 0)
(2, 0): (2, 0, 0)
(3, 0): (3, 0, 0)
(4, 0): (4, 0, 0)
(5, 0): (5, 0, 0)
(6, 0): (6, 0, 0)
(7, 0): (7, 0, 0)
(8, 0): (8, 0, 0)
(9, 0): (9, 0, 0)
(10, 0): (10, 0, 0)

with all B values showing '0' with the exception of one at 'x' position 77 which shows:
(77, 0): (77, 0, 8)

How can I get the list to print out all 'B' values > 0. I tried somehow incorporating mine with yours but I can't get it to work right. Thanks

Wait a sec.....after playing around with sneekula's code for a while, I realized that it works, it's just printing out 1 row.

# testing ...
# show contents of the first row
y = 0
for x in range(width):
    print( "(%d, %d): %s"% (x, y, pixel_dict[(x, y)]) )

so I guess I just need a way to make it loop through all rows.
I figured this out by adding:
y += 1 below y=0 and saw that it printed out the 2nd row. What's the way to get it to loop through all rows?

I wanted to edit the above thread but anyway.....I got it to loop through so now the last thing I need to work out is how to get it to print out just the values where 'B' is > 0, like in the first code I posted. I'm trying to adjust the code but haven't gotten it yet.

I'm bumping this thread to see if I can get a reply....the code by sneekula works for what I need but I can't figure out how to get it to just print out the ones where the 'B' value is greater than 0, which in the image I gave would be this one:
(77, 0): (77, 0, 8)

I guess I would need to add an 'if pixel[2] >0:' statement in and I've tried that in several locations but keep getting error messages.
any help?

I guess I would need to add an 'if pixel[2] >0:' statement in and I've tried that in several locations but keep getting error messages.
any help?

That's right... so what are the error messages?

By showing us your mistakes we can help you resolve them. That way, you learn and grow as a programmer. Then you won't have to ask about it next time you need to do something similar.

So everybody wins!

When I run this:

from PIL import Image

img = Image.open('10x.bmp')
for pixel in img.getdata():
    if pixel[2] > 0:
        print pixel

it works but doesn't have the x,y positions. When I try sneelula's code it works but I need to narrow down the list. So...things I've tried:

for y in range(height):
    # columns
    for x in range(width):
        for pixel in pixel_list:
            if pixel[2] > 0:
              pixel_dict[(x, y)] = pixel_list[ix]
              #print x, y, ix
              ix += 1

pixel_dict[(x, y)] = pixel_list[ix]
IndexError: list index out of range
or changing pixel_list to pixel:

for pixel in img.getdata():
    if pixel[2] > 0:
        print pixel
 

# create a (x,y):(r,g,b) dictionary
# where (x,y) are the location coordinates an image point
# and (r,g,b) is the value of the pixel at that point
pixel_dict = {}
ix = 0

# rows
for y in range(height):
    # columns
    for x in range(width):
        pixel_dict[(x, y)] = pixel[ix]
        #print x, y, ix
        ix += 1

pixel_dict[(x, y)] = pixel[ix]
IndexError: tuple index out of range
or changing this part:

y = 0
for x in range(width):
  for pixel in img.getdata():
     if pixel[2] > 0:
       print( "(%d, %d): %s"% (x, y, pixel_dict[(x, y)]) )

that just prints out a very long list.

:) I think I figured it out:

y = 0
for x in range(width):
    if pixel_dict[(x,y)][2] > 0:
     print( "(%d, %d): %s"% (x, y, pixel_dict[(x, y)]) )

:) I think I figured it out:

y = 0
for x in range(width):
    if pixel_dict[(x,y)][2] > 0:
     print( "(%d, %d): %s"% (x, y, pixel_dict[(x, y)]) )

Well? Did it work? Do you think you figured it out or did you figure it out?

This article has been dead for over six months. Start a new discussion instead.