TypeError: cannot unpack non-iterable int object occurring with grayscale file

Viewed 58

I want to convert a file to grayscale in python using PIL and then get the x,y and rgb value of the pixels but I am getting an error.

Code:


from PIL import Image,ImageOps
file_name = "test.png"
og_image = Image.open(file_name)
gray_image = ImageOps.grayscale(og_image)
gray_scalefile = f"{file_name[:-3]}gray.png"
gray_image.save(gray_scalefile)
img = Image.open(gray_scalefile)
pixels = img.load() 
width, height = img.size
for x in range(width):
    for y in range(height):
        r, g, b = pixels[x, y]
        print(x, y, f"{r},{g},{b}")

contents of text.png: enter image description here

contents of text.gray.png: enter image description here

The code works fine with the text.png but when I grayscale it just doesn't work and gives me this error.

Traceback (most recent call last):
  File "d:\Image Manipulation\Image Manipulation.py", line 12, in <module>
    r, g, b = pixels[x, y]
TypeError: cannot unpack non-iterable int object

2 Answers
file_name = "test.jpg"
og_image = Image.open(file_name)
gray_image = ImageOps.grayscale(og_image)
gray_scalefile = f"{file_name[:-3]}gray.jpg"
gray_image.save(gray_scalefile)
img = Image.open(gray_scalefile).convert('RGB')
pixels = img.load()
width, height = img.size
for x in range(width):
    for y in range(height):
        r,g,b= pixels[x, y]
        print(x, y, f'{r},{g},{b}')

This will work, cause it converts Luminescence to rgb first

i just wanted to raise some doubts about the initial post:

the error message TypeError: cannot unpack non-iterable int object indicates, that the line: r, g, b = pixels[x, y] is not returning 3 values (as RGB), but just one value. this is because a gray scale image does have only one plane / channel. to solve this issue we can use this: value = pixels[x, y]

here is my suggestion:

from PIL import Image
img = Image.open("test_rgb.png").convert("L")
img.save("test_gray_scale.png")
pixels = img.load()
for x in range(img.size[0]):
    for y in range(img.size[1]):
        value = pixels[x, y]
        print(f'{x=} {y=}  {value}')
img.close() # don't forget to close the image object
Related