【问题标题】:Pyautogui and pyscreeze crash with windll.user32.ReleaseDC failedPyautogui 和 pyscreez 崩溃,windll.user32.ReleaseDC 失败
【发布时间】:2021-09-14 12:29:04
【问题描述】:

我正在尝试比较我的 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 版,所以理论上一切都应该是最新的,但不知何故最终崩溃了。有没有办法缓解这种情况,要么修改我的代码,甚至修改库本身,还是我的环境不适合这个操作?

【问题讨论】:

  • 这现在是fixed in pyscreeze-1.0.28pyautogui 使用它以及错误所在的位置)。

标签: windows pyautogui python-3.8 pyscreeze


【解决方案1】:

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

在 Windows 上,只要安装了 3.7,就可以使用-3.7 命令行标志来完成

【讨论】:

  • 这现在是pyscreeze-1.0.28 中的fixedpyautogui 使用它并且错误所在的位置)。
【解决方案2】:

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

如需了解更多信息,请参阅报告的 GitHub 问题:https://github.com/asweigart/pyscreeze/pull/73

【讨论】:

  • 刚刚在运行 0.1.28 时发生错误
  • 重新签入,仍然弹出错误。
【解决方案3】:

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

with __win32_openDC(0) as hdc

该函数使用cyptes.windll,它似乎不适用于有时从windll.user32.GetDC() 返回的负值,随后在调用windll.user32.ReleaseDC() 时会产生异常。

pillow 的人们帮助追踪了这个问题并提出了解决方案。

  • issue 归档于 pyautogui
  • issue 在枕头上提交了解决方案
  • pending PR 在 pyscreez 的地址

【讨论】:

    【解决方案4】:

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

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

    我不知道为什么会这样,但确实有效。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

        猜你喜欢
        • 2021-03-19
        • 1970-01-01
        • 2022-09-26
        • 2012-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-11
        相关资源
        最近更新 更多