I assume you are getting an error like.. TypeError: 'PixelAccess' object is not iterable
...?
See the Image.load documentation for how to access pixels..
Basically, to get the list of pixels in an image, using PIL
:
from PIL import Image
i = Image.open("myfile.png")
pixels = i.load() # this is not a list, nor is it list()'able
width, height = i.size
all_pixels = []
for x in range(width):
for y in range(height):
cpixel = pixels[x, y]
all_pixels.append(cpixel)
That appends every pixel to the all_pixels
- if the file is an RGB image (even if it only contains a black-and-white image) these will be a tuple, for example:
(255, 255, 255)
To convert the image to monochrome, you just average the three values - so, the last three lines of code would become..
cpixel = pixels[x, y]
bw_value = int(round(sum(cpixel) / float(len(cpixel))))
# the above could probably be bw_value = sum(cpixel)/len(cpixel)
all_pixels.append(bw_value)
Or to get the luminance (weighted average):
cpixel = pixels[x, y]
luma = (0.3 * cpixel[0]) + (0.59 * cpixel[1]) + (0.11 * cpixel[2])
all_pixels.append(luma)
Or pure 1-bit looking black and white:
cpixel = pixels[x, y]
if round(sum(cpixel)) / float(len(cpixel)) > 127:
all_pixels.append(255)
else:
all_pixels.append(0)
There is probably methods within PIL to do such RGB -> BW
conversions quicker, but this works, and isn't particularly slow.
If you only want to perform calculations on each row, you could skip adding all the pixels to an intermediate list.. For example, to calculate the average value of each row:
from PIL import Image
i = Image.open("myfile.png")
pixels = i.load() # this is not a list
width, height = i.size
row_averages = []
for y in range(height):
cur_row_ttl = 0
for x in range(width):
cur_pixel = pixels[x, y]
cur_pixel_mono = sum(cur_pixel) / len(cur_pixel)
cur_row_ttl += cur_pixel_mono
cur_row_avg = cur_row_ttl / width
row_averages.append(cur_row_avg)
print "Brighest row:",
print max(row_averages)