PyAutoGUI allocateAllOnScreen 无法规避 ImageNotFoundException

问题描述 投票:0回答:1

我正在编写一个小脚本来自动执行游戏中一项烦人的任务。为此,我需要比较屏幕截图。当我使用 LocateCenterOnScreen 时,它工作得很好,除了它只找到第一次出现的情况。但我想要所有的出现,所以我将其更改为locateAllOnScreen。但是当我这样做时,屏幕上没有任何内容,它会抛出 ImageNotFoundException 并告诉我降低置信度(没有匹配项,我手动检查,所以降低置信度不是我想要的)

我可以以某种方式捕获异常以保持其运行吗?

错误信息:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Users\name\AppData\Local\Programs\Python\Python39\lib\threading.py", line 980, in _bootstrap_inner
    self.run()
  File "C:\Users\name\AppData\Local\Programs\Python\Python39\lib\threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\name\PycharmProjects\LeafBlowerTrade\main.py", line 31, in start
    for pos in locs:
  File "C:\Users\name\PycharmProjects\LeafBlowerTrade\venv\lib\site-packages\pyscreeze\__init__.py", line 257, in _locateAll_opencv
    raise ImageNotFoundException('Could not locate the image (highest confidence = %.3f)' % result.max())
pyscreeze.ImageNotFoundException: Could not locate the image (highest confidence = 0.550)

这是我在代码中尝试的,但它不起作用。当我使用locateCenterOnScreen 时,完全相同的代码有效。

try:
  locs = locateAllOnScreen(icon, confidence=0.6)
except ImageNotFoundException:
  pass

整个代码是:

from pyautogui import *
import time
import threading
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode


TOGGLE_KEY = KeyCode(char="p")

running = False
mouse = Controller()


def toggle_event(key):
    if key == TOGGLE_KEY:
        global running
        running = not running
        print(position())


def start():
    icon = 'Gem.png'
    while True:
        if running:
            locs = []
            try:
                locs = locateAllOnScreen(icon, confidence=0.6)
            except ImageNotFoundException:
                pass
            for pos in locs:
                x = pos[0] + int(pos[2] / 2)
                y = pos[1] + int(pos[3] / 2)
                moveTo(x + 768, y)
                mouse.press(Button.left)
                time.sleep(0.02)
                mouse.release(Button.left)
            moveTo(1557, 1124)
            mouse.press(Button.left)
            time.sleep(0.02)
            mouse.release(Button.left)
            moveTo(606, 1126)
            mouse.press(Button.left)
            time.sleep(0.02)
            mouse.release(Button.left)
            moveTo(2008, 1123)
            mouse.press(Button.left)
            time.sleep(0.02)
            mouse.release(Button.left)
        time.sleep(0.1)


run_thread = threading.Thread(target=start)
run_thread.start()

with Listener(on_press=toggle_event) as listener:
    listener.join()

locateCenterOnScreen 的工作代码是:

from pyautogui import *
import time
import threading
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode


TOGGLE_KEY = KeyCode(char="p")

running = False
mouse = Controller()


def toggle_event(key):
    if key == TOGGLE_KEY:
        global running
        running = not running
        print(position())


def start():
    icon = 'Gem.png'
    while True:
        if running:
            try:
                position = locateCenterOnScreen(icon, confidence=0.7)
                x, y = position
                moveTo(x+768, y)
                mouse.press(Button.left)
                time.sleep(0.02)
                mouse.release(Button.left)
                moveTo(1557, 1124)
                mouse.press(Button.left)
                time.sleep(0.02)
                mouse.release(Button.left)
                moveTo(606, 1126)
                mouse.press(Button.left)
                time.sleep(0.02)
                mouse.release(Button.left)
            except ImageNotFoundException:
                moveTo(606, 1126)
                mouse.press(Button.left)
                time.sleep(0.02)
                mouse.release(Button.left)
            moveTo(2008, 1123)
            mouse.press(Button.left)
            time.sleep(0.02)
            mouse.release(Button.left)
        time.sleep(0.1)


run_thread = threading.Thread(target=start)
run_thread.start()

with Listener(on_press=toggle_event) as listener:
    listener.join()
python screenshot pyautogui
1个回答
0
投票

首先,尝试做

try:
    locs = locateAllOnScreen(icon, confidence=0.6)
except pyscreeze.ImageNotFoundException:
    pass

有时,准确指定要避免的异常可以帮助解决问题。

解决问题的另一种方法是使用

locateCenterOnScreen
并创建一个覆盖该区域的新图像。您可以通过使用
cv2.rectangle method
并在循环中提供新图像来实现此目的。这是一种更复杂的方法,并且认为没有必要。

使用

locateCenterOnScreen
时的第二种解决方案是以网格样式检查屏幕。例如:

def start():
icon = 'Gem.png'

# Replace img_x and img_y with Gem.png’s x and y.
# The first region will be [0,0,img_x,img_y].
reg = (0,0,img_x,img_y)

while True:
    if running:
        try:
            position = locateCenterOnScreen(icon, region=reg, confidence=0.7)
            x, y = position
            # rest of your code here

            change_reg = list(reg)
            change_reg[0], change_reg[2] = int(change_reg[0]) + img_x, int(change_reg[2]) + img_x
            reg = tuple(change_reg)
         except ImageNotFoundException:
            # rest of your code

            change_reg = list(reg)
            change_reg[0], change_reg[2] = int(change_reg[0]) + img_x, int(change_reg[2]) + img_x
            reg = tuple(change_reg)

这不是确切的代码,但比较接近;一旦超出屏幕,您就必须对其进行修改才能更改 y 值。

我目前没有计算机来尝试这些,因此它们可能无法按预期工作或根本无法工作。对不起!

© www.soinside.com 2019 - 2024. All rights reserved.