【问题标题】:How to detect an image and click it with pyautogui?如何检测图像并使用pyautogui单击它?
【发布时间】:2021-11-07 05:15:50
【问题描述】:

我想学习如何让机器人点击图像,我尝试观看 yt 教程但我找不到代码中的错误在哪里,因为这实际上是我第一次使用 python,我尝试了以下代码:

from pyautogui import *
import pyautogui
import time
import keyboard
import random
import win32api, win32con

time.sleep(5)

def click():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)

while keyboard.is_pressed('q') == False:
    flag = 0
    
    if pyautogui.locateOnScreen('benz.png', region=(0,0,1366,768), grayscale=True, confidence=0.5) != None:
                flag = 1
                click()
                time.sleep(0.05)
                break

                
                if flag == 1:
                 break

但我一直得到:

Traceback (most recent call last):
  File "c:\Program Files\Karim\autoclicker\main+stickman.py", line 17, in <module>
    if pyautogui.locateOnScreen('benz.png', region=(0,0,1366,768), grayscale=True, confidence=0.5) != None:
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\lib\site-packages\pyautogui\__init__.py", line 175, in wrapper
    return wrappedFunction(*args, **kwargs)
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\lib\site-packages\pyautogui\__init__.py", line 213, in locateOnScreen
    return pyscreeze.locateOnScreen(*args, **kwargs)
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\lib\site-packages\pyscreeze\__init__.py", line 373, in locateOnScreen
    retVal = locate(image, screenshotIm, **kwargs)
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\lib\site-packages\pyscreeze\__init__.py", line 353, in locate
    points = tuple(locateAll(needleImage, haystackImage, **kwargs))
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\lib\site-packages\pyscreeze\__init__.py", line 207, in _locateAll_opencv
    needleImage = _load_cv2(needleImage, grayscale)
  File "C:\Users\bayan\AppData\Local\Programs\Python\Python310\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 benz.png because file is missing, has improper permissions, or is an unsupported or invalid format

注意:benz.png文件与代码在同一个文件夹中,为png格式,实际上是一张照片(即双击打开并显示一张照片)

代码中可能有一个我不知道的愚蠢错误,因为我对 python 几乎一无所知????

【问题讨论】:

    标签: python pyautogui


    【解决方案1】:

    这可能是权限问题,因为pyautogui 在多个脚本实例中运行并且无法访问正确的文件。

    在任何情况下,您都可以通过直接读取文件来解决此问题,例如:

    from cv2 import imread
    image = imread('benz.png')
    if pyautogui.locateOnScreen(image,... # and so on 
    

    【讨论】:

    • 这是我当前的代码 pastebin.com/nBisgEhY 但显然,我遇到了这些问题 ibb.co/9hyqnf6
    • 我把它编辑成这个pastebin.com/vC65YHWh我摆脱了这些问题,但我仍然得到同样的错误OSError: Failed to read benz.png because file is missing, has improper permissions, or is an unsupported or invalid format
    • 但是,当我使用print(os.listdir(r"C:\Program Files\Karim\Others\autoclicker")) 时出现benz.png
    【解决方案2】:

    PyAutoGUI 有一个内置的function 称为locateOnScreen(),如果它可以在当前屏幕上找到它,它会返回图像中心的x,y 坐标(它会截取屏幕截图然后分析它)。

    图片必须完全匹配才能正常工作;即,如果您想单击button.png,则该按钮图片必须与窗口中的按钮具有相同的大小/分辨率,以便程序识别它。实现此目的的一种方法是截取屏幕截图,在绘图中打开它,然后只剪下您想要按下的按钮(或者您可以让 PyAutoGUI 为您完成,我将在后面的示例中展示)。

    import pyautogui
    
    question_list = ['greencircle', 'redcircle', 'bluesquare', 'redtriangle']
    
    user_input = input('Where should I click? ')
    
    while user_input not in question_list:
        print('Incorrect input, available options: greencircle, redcircle, bluesquare, redtriangle')
        user_input = input('Where should I click?')
    
    location = pyautogui.locateOnScreen(user_input + '.png')
    pyautogui.click(location)
    

    上面的例子要求你已经有greencircle.png 和你的目录中的所有其他.png

    PyAutoGUI 也可以拍摄screenshots 并且您可以指定屏幕的哪个区域拍摄pyautogui.screenshot(region=(0, 0, 0, 0)) 前两个值是您要选择的区域左上角的 x,y 坐标,第三个是向右多远(x),第四是向下多远(y)。

    以下示例截取 Windows 10 徽标,将其保存到文件中,然后使用指定的 .png 文件单击徽标

    import pyautogui
    
    pyautogui.screenshot('win10_logo.png', region=(0, 1041, 50, 39))
    location = pyautogui.locateOnScreen('win10_logo.png')
    pyautogui.click(location)
    

    您也不必将屏幕截图保存到文件中,只需将其保存为变量即可

    import pyautogui
    
    win10 = pyautogui.screenshot(region=(0, 1041, 50, 39))
    location = pyautogui.locateOnScreen(win10)
    pyautogui.click(location)
    

    让程序检测用户是否点击了某个区域(比如说,Windows 10 徽标)将需要另一个库,例如 pynput

    from pynput.mouse import Listener    
    
    def on_click(x, y, button, pressed):
        if 0 < x < 50 and 1080 > y > 1041 and str(button) == 'Button.left' and pressed:
            print('You clicked on Windows 10 Logo')
            return False    # get rid of return statement if you want a continuous loop
    
    with Listener(on_click=on_click) as listener:
        listener.join()
    

    把它们放在一起

    import pyautogui
    from pynput.mouse import Listener
    
    win10 = pyautogui.screenshot(region=(0, 1041, 50, 39))
    location = pyautogui.locateOnScreen(win10)
    
    # location[0] is the top left x coord
    # location[1] is the top left y coord
    # location[2] is the distance from left x coord to right x coord
    # location[3] is the distance from top y coord to bottom y coord
    
    x_boundary_left = location[0]
    y_boundary_top = location[1]
    x_boundary_right = location[0] + location[2]
    y_boundary_bottom = location[1] + location[3]
    
    
    def on_click(x, y, button, pressed):
        if x_boundary_left < x < x_boundary_right and y_boundary_bottom > y > y_boundary_top and str(button) == 'Button.left' and pressed:
            print('You clicked on Windows 10 Logo')
            return False    # get rid of return statement if you want a continuous loop
    
    
    with Listener(on_click=on_click) as listener:
        listener.join()
    

    【讨论】:

      【解决方案3】:

      我编辑了:

      if pyautogui.locateOnScreen('benz.png', region=(0,0,1366,768), grayscale=True, confidence=0.5) != None:
      

      到:

      if pyautogui.locateOnScreen('C:/Program Files/Karim/Others/benz.png', region=(0,0,1366,768), grayscale=True, confidence=0.5) != None:
      

      它成功了?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-12
        • 2021-02-19
        • 2019-04-22
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 2021-04-26
        • 1970-01-01
        相关资源
        最近更新 更多