Home > Back-end >  How do I specify multiple regions with pyautogui?
How do I specify multiple regions with pyautogui?

Time:11-04

There are four regions on my screen someButton.png that may appear in. I would like to specify these 4 regions rather than the entire screen.

I know we can specify single regions like the below example, but the documentation doesn't say anything about multiple regions.

    import pyautogui
    pyautogui.locateOnScreen('someButton.png', region=(0,0, 300, 400))

I've tried adding multiple keyword:

pyautogui.locateOnScreen('someButton.png', region=(0,0, 300, 400), region=(0,0, 400, 500))

but I get the error SyntaxError: keyword argument repeated: region

How do I specify multiple regions to search for in pyautogui?

Edit** Update for comments**

The code I'm working with now:

def l():
    l = py.locateOnScreen(levelupimage, confidence=0.90)

    regions = {
        "region 1": (476, 268, 736, 320),
        "region 2": (1328, 268, 1591, 320),
        "region 3": (276, 745, 564, 806),
        "region 4": (1130, 745, 1422, 803)
    }

    for region in regions:
        l = py.locateOnScreen('levelup.jpg', region=region)
        if l != None:
            py.click(l)

And the error message:

Traceback (most recent call last):
  File "c:\Users\x\OneDrive\froggy-pirate-master\avoidShips\eventfarm\eventfarm.py", line 201, in <module>
    daily()
  File "c:\Users\x\OneDrive\froggy-pirate-master\avoidShips\eventfarm\eventfarm.py", line 191, in daily
    levelup()
  File "c:\Users\x\OneDrive\froggy-pirate-master\avoidShips\eventfarm\eventfarm.py", line 55, in levelup
    levelup = py.locateOnScreen('levelup.jpg', region=region)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyautogui\__init__.py", line 175, in wrapper
    return wrappedFunction(*args, **kwargs)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyautogui\__init__.py", line 213, in locateOnScreen
    return pyscreeze.locateOnScreen(*args, **kwargs)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyscreeze\__init__.py", line 373, in locateOnScreen
    retVal = locate(image, screenshotIm, **kwargs)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyscreeze\__init__.py", line 353, in locate
    points = tuple(locateAll(needleImage, haystackImage, **kwargs))
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyscreeze\__init__.py", line 207, in _locateAll_opencv
    needleImage = _load_cv2(needleImage, grayscale)
  File "C:\Users\x\AppData\Local\Programs\Python\Python39\lib\site-packages\pyscreeze\__init__.py", line 170, in _load_cv2
    raise IOError("Failed to read %s because file is missing, "
OSError: Failed to read l.jpg because file is missing, has improper permissions, or is an unsupported or invalid format

l is being loaded above the function l = r"C:\Users\x\OneDrive\froggy-pirate-master\avoidShips\eventfarm\l.jpg"

The file is still there, does passing the region tuples across in a loop change the format of something?

CodePudding user response:

regions = {
    "region 1": (0, 0, 300, 400),
    "region 2": (300, 0, 300, 400),
    "region 3": (0, 400, 300, 400),
    "region 4": (300, 400, 300, 400)
}
for region_name, region in regions.items():
    rect = pyautogui.locateOnScreen('someButton.png', region=region)
    if rect:
        print(f"found in {region_name} at this (x,y,w,h): {rect}")

I had a look at the source code, and since the part that finds an image in a region can be quite slow, linearly with the possible image positions, it's better to call locateOnScreen separately for every region (as opposed to calling it once on a region that contains your four regions).

Reading the source code it also seems that, for speed, you should have both cv2 (OpenCV) and numpy installed. If you have only one of them, or none, it will fall back to using pillow.

  • Related