3

我正在尝试比较我的 pyautogui 脚本中的某些像素值,但它在多次成功运行后崩溃并出现以下错误消息,或者有时只是在第一次调用时直接崩溃:

Traceback (most recent call last):
  File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 219, in <module>
    battle = observeBattle()
  File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 180, in observeBattle
    statii = getHeroBattlePixels()
  File "F:\Koodit\Python\HeroWars NNet\Assets\autodataGet.py", line 32, in getHeroBattlePixels
    colormatch = pyautogui.pixelMatchesColor(location[0], location[1], alive, tolerance=5)
  File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 557, in pixelMatchesColor
    pix = pixel(x, y)
  File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 582, in pixel
    return (r, g, b)
  File "E:\Program Files\Python\lib\contextlib.py", line 120, in __exit__
    next(self.gen)
  File "E:\Program Files\Python\lib\site-packages\pyscreeze\__init__.py", line 111, in __win32_openDC
    raise WindowsError("windll.user32.ReleaseDC failed : return 0")
OSError: windll.user32.ReleaseDC failed : return 0

我的代码(这被多次调用,有时它在第一次运行时崩溃,有时它在失败之前很好地运行了大约 100 次调用,另外,我的屏幕是 4K,所以分辨率变大了):

def getSomePixelStatuses():
    someLocations= [
                        [1200, 990],
                        [1300, 990],
                        [1400, 990],
                        [1500, 990],
                        [1602, 990],
                        [1768, 990],
                        [1868, 990],
                        [1968, 990],
                        [2068, 990],
                        [2169, 990]
                        ]
    status = []
    someValue= (92, 13, 12)
    for location in someLocations:
        colormatch = pyautogui.pixelMatchesColor(location[0], location[1], someValue, tolerance=5)
        status.append(colormatch)
    return status

我不知道如何缓解这个问题。看起来 pyautogui 使用 pyscreez 来读取屏幕上的像素值,最有可能出现错误的地方是 pyscreez 像素函数:

def pixel(x, y):
    """
    TODO
    """
    if sys.platform == 'win32':
        # On Windows, calling GetDC() and GetPixel() is twice as fast as using our screenshot() function.
        with __win32_openDC(0) as hdc: # handle will be released automatically
            color = windll.gdi32.GetPixel(hdc, x, y)
            if color < 0:
                raise WindowsError("windll.gdi32.GetPixel failed : return {}".format(color))
            # color is in the format 0xbbggrr https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
            bbggrr = "{:0>6x}".format(color) # bbggrr => 'bbggrr' (hex)
            b, g, r = (int(bbggrr[i:i+2], 16) for i in range(0, 6, 2))
            return (r, g, b)
    else:
        # Need to select only the first three values of the color in
        # case the returned pixel has an alpha channel
        return RGB(*(screenshot().getpixel((x, y))[:3]))

我昨天刚刚安装了这些库,我在 Windows 10 上运行 python 3.8,而 pyscreez 是 0.1.25 版,所以理论上一切都应该是最新的,但不知何故最终崩溃了。有没有办法缓解这种情况,要么修改我的代码,甚至修改库本身,还是我的环境不适合这个操作?

4

5 回答 5

7

好吧,我知道这不是特别有用;但对我来说,只需在 3.7 而不是 3.8 上运行我的代码即可修复此错误。但是,您不必对代码进行任何更改(除非您使用的是海象!)

在 Windows 上,这可以通过-3.7命令行标志来完成,只要安装了 3.7

于 2020-01-05T00:05:18.703 回答
2

这是一个错误。您走在正确的轨道上,因为问题确实出在pixel()函数的这一行中:

with __win32_openDC(0) as hdc

该函数使用cyptes.windllwhich 似乎不能很好地处理有时从 中返回的负值windll.user32.GetDC(),随后在调用时会产生异常windll.user32.ReleaseDC()

pillow帮助追踪此问题并提出解决方案的人。

于 2021-06-15T15:09:03.613 回答
2

PyScreeeze 和 PyAutoGUI 维护者在这里。这是 PyScreeeze 0.1.28 中已修复的问题,因此您只需运行pip install -U pyscreeze.

有关更多上下文,这是报告的 GitHub 问题:https ://github.com/asweigart/pyscreez/pull/73

于 2021-09-14T04:29:04.277 回答
0

我可以pixel像这样在 Python 3.8 上使用函数:

try:
    a = pixel(100,100)
> except:
>     a = pixel(100,100)

我不知道为什么这有效,但它有效。

于 2020-12-24T17:59:00.470 回答
-1

我也有这个错误,我修复了它。只需使用 try 和 except。虽然为真:尝试:x,y = pyautogui.position() print(pyautogui.pixel(x,y)) 除外:print("暂时无法获取像素")

考虑到您可能会多次获取像素,或者您可以这样做,请尝试并尝试解决任何 pyscreez for pyautogui 问题的奇迹。老实说,我不知道 pyscreeeze 是怎么回事,但这对我有用。干杯

于 2020-11-17T09:19:50.290 回答