Object is not Subscriptable Screen Recording

I am trying to record my screen while checking individual pixels in the recording for colors. I have successfully created a live recording of my screen, but when I try to check the pixels of this recording I get this error: TypeError: 'Image' object is not subscriptable. Here is my code:

import cv2
import numpy as np
from mss import mss
from PIL import Image

mon = {'left': 500, 'top': 850, 'width': 450, 'height': 30}

with mss() as sct:
    while True:
        screenShot = sct.grab(mon)
        img = Image.frombytes('RGB', (screenShot.width, screenShot.height),
                              screenShot.rgb, 
        )
        px = img[10,25]
        print(px)
        
        cv2.imshow('test', np.array(img))
        if cv2.waitKey(33) & 0xFF in (
            ord('q'), 
            27, 
        ):
            break

If anyone has any ideas about what is wrong please tell me. Thanks!

I don’t know the pillow API, but from a glance at their docs, it looks like you should use Image.getpixel() to extract pixels. AFAICS from the pillow docs, the error message you get is quite correct; the Image class is not subscriptable.

I’m a total noob with this library, but I agree with you, on the doc it does say that Image.getpixel() will work. But when I run the program I get a new error message:

Traceback (most recent call last):
  File "/Users/nbagley/Desktop/MinecraftShocker.py", line 15, in <module>
    px = Image.getpixel(0, 0)
  File "/Users/nbagley/Library/Python/3.9/lib/python/site-packages/PIL/Image.py", line 77, in __getattr__
    raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
AttributeError: module 'PIL.Image' has no attribute 'getpixel'

I think that I am using this function the right way, but I don’t know, here is my code:

import cv2
import numpy as np
from mss import mss
from PIL import Image

mon = {'left': 500, 'top': 850, 'width': 450, 'height': 30}

with mss() as sct:
    while True:
        screenShot = sct.grab(mon)
        img = Image.frombytes('RGB', (screenShot.width, screenShot.height),
                              screenShot.rgb, 
        )

        px = Image.getpixel(0, 0)
        print(px)
        
        cv2.imshow('test', np.array(img))
        if cv2.waitKey(33) & 0xFF in (
            ord('q'), 
            27, 
        ):
            break

Thanks for your help!

Disclaimer: I have not used this library. Simply reading what is posted so far …

You’ve created an image object with the line

img = Image.frombytes('RGB', (screenShot.width, screenShot.height),
                              screenShot.rgb, 
        )

Now, use the getpixel method with this object

px = img.getpixel(0, 0)
1 Like

Thanks, I did what you told me, but I got this error: getpixel() takes 2 positional arguments but 3 were given. Then realized that the coordinates have to be in a tuple, so I finally got it working with

px = img.getpixel((0, 0))

Thanks everyone!

1 Like