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

Question:

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 ManipulationImage Manipulation.py", line 12, in <module>
    r, g, b = pixels[x, y]
TypeError: cannot unpack non-iterable int object

Asked By: Zen35X

||

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

Answered By: Albert_coding

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
Answered By: lroth