asweigart / pyautogui

A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard.
BSD 3-Clause "New" or "Revised" License
10.22k stars 1.24k forks source link

Pyautogui "pixelMatchesColor" Returning -1 with OSError #688

Open michaelt47 opened 2 years ago

michaelt47 commented 2 years ago

I'm trying to run a python program I wrote to automate a game found here: https://color.method.ac/ For now I'm just trying to get through one iteration of the color wheel, but I'm running into a weird error where when the code runs py.pixelMatchesColor, it returns -1 with the error: Traceback (most recent call last): File "C:\Users\myuser\Documents\color.py", line 27, in <module> if py.pixelMatchesColor(h, j, pix, tolerance=100) == True: File "C:\Users\myuser\AppData\Roaming\Python\Python37\site-packages\pyscreeze\__init__.py", line 589, in pixelMatchesColor pix = pixel(x, y) File "C:\Users\myuser\AppData\Roaming\Python\Python37\site-packages\pyscreeze\__init__.py", line 610, in pixel raise WindowsError("windll.gdi32.GetPixel failed : return {}".format(color)) OSError: windll.gdi32.GetPixel failed : return -1 Here is my code:


import math
import pyautogui as py
import time
py.FAILSAFE = True

py.moveTo(940, 559)
py.click()

time.sleep(6)

pix = py.pixel(962, 472)

for x in range(360):

    print(round(955+(289*math.sin(x))))
    h = round(955+(289*math.cos(x)))
    j = round(955+(289*math.sin(x)))
    if py.pixelMatchesColor(h, j, pix, tolerance=100) == True:
        print("It's Done")

        py.moveTo(955+(289*math.cos(x)), 955+(289*math.sin(x)))
        py.click()
        break

What is causing this error?

JayRizzo commented 2 years ago

What is pix returning as a value?

It worked for me, but I'm on a mac & got an issue with the Image package not installing.

File ".../pyscreeze/__init__.py", line 477, in _screenshot_osx

So, I am thinking it might be an issue with one of the dependancies:

Could you try running this?

pip install Image --upgrade

OR

pip3 install Image --upgrade

Then try again.

This is what I tried:

import math
import pyautogui as py
import time

py.FAILSAFE = True
py.moveTo(940, 559)
# py.click()
# time.sleep(6)
pix = py.pixel(962, 472)

for x in range(360):
    print(round(955+(289*math.sin(x))))
    h = round(955+(289*math.cos(x)))
    j = round(955+(289*math.sin(x)))
    if py.pixelMatchesColor(h, j, pix, tolerance=100) == True:
        py.moveTo(955+(289*math.cos(x)), 955+(289*math.sin(x)))
        # py.click()
        print("It's Done")
        print("Test 1: {}".format(pix))
        break
    else:
        print("Test 2: {}".format(pix))

print("Test 3: {}".format(pix))

and got as a Result from my terminal:

    # jayrizzo$ python3
    # Python 3.9.5 (v3.9.5:0a7dcbdb13, May  3 2021) 
    # [Clang 6.0 (clang-600.0.57)] on darwin
    # Type "help", "copyright", "credits" or "license" for more information.

    >>> import math
    >>> import pyautogui as py
    >>> import time
    >>> 
    >>> py.FAILSAFE = True
    >>> py.moveTo(940, 559)
    >>> # py.click()
    >>> # time.sleep(6)
    >>> pix = py.pixel(962, 472)
    >>> 
    >>> for x in range(360):
    ...     print(round(955+(289*math.sin(x))))
    ...     h = round(955+(289*math.cos(x)))
    ...     j = round(955+(289*math.sin(x)))
    ...     if py.pixelMatchesColor(h, j, pix, tolerance=100) == True:
    ...         py.moveTo(955+(289*math.cos(x)), 955+(289*math.sin(x)))
    ...         # py.click()
    ...         print("It's Done")
    ...         print("Test 1: {}".format(pix))
    ...         break
    ...     else:
    ...         print("Test 2: {}".format(pix))
    ... 
    # 955
    # It's Done
    # Test 1: RGB(red=6, green=6, blue=6)
    >>> print("Test 3: {}".format(pix))
    # Test 3: RGB(red=6, green=6, blue=6)
    >>> 
    >>> 
michaelt47 commented 2 years ago

I’ll have to try it soon, hopefully it works out.

michaelt47 commented 2 years ago

Alright, I fixed everything. I ended up realizing the code was reading trig in radians and not degrees which messed a lot of things up, and I also had a few other errors. Here's my finished code:

import math
import pyautogui as py
import time
py.FAILSAFE = False

py.moveTo(940, 559)
py.click()
time.sleep(6)

for i in range(5):
        x = 0
        pix = py.pixel(962, 472)
        while True:
                h = round(955 + (289*math.cos(math.radians(x))))
                j = round(550 + (289*math.sin(math.radians(x))))
                try:
                        if py.pixelMatchesColor(h, j, pix, tolerance=20):
                                py.moveTo(h, j)
                                py.click()
                                break
                except OSError:
                        print('OSError')
                x = x + 3
        time.sleep(2)

The way I have it wrote shouldn't even bring up the error anymore, but it was definitely a weird one.

JayRizzo commented 2 years ago

Hey @michaelt47, Thanks for the response I was tinkering with your example here are some ideas.

Uniform might provide more of a human feel. randint might slightly change up the location of the check. some other minor adjustments let me know what you think? I commented out the clicks for testing.

from random import randint
from random import uniform
import math
import pyautogui as py
import time

py.FAILSAFE = False
py.moveTo(940, 559, uniform(1, 3))
# py.click()
for i in range(5):
    pix = py.pixel(962, 472)
    x = 0
    while True:
        try:
            h = round(955 + randint(1,5) + (289 * math.cos(math.radians(x))))
            j = round(550 + randint(1,5) + (289 * math.sin(math.radians(x))))
            if py.pixelMatchesColor(h, j, pix, tolerance=20):
                py.moveTo(h, j, uniform(1, 3))
                # py.click()
                break
        except OSError:
            print('OSError')
        finally:
            x += 3
            print(f"X:{x}")
            print(f"H:{h}")
            print(f"J:{j}")
            time.sleep(2)

# Results
# X:3
# H:1249
# J:554
# X:3
# H:1246
# J:554
# X:3
# H:1247
# J:551
# X:3
# H:1247
# J:555
# X:3
# H:1248
# J:552