Pyautogui 和 pyscreeze 使用 windll 崩溃。user32.ReleaseDC 失败
Pyautogui and pyscreeze crash with windll.user32.ReleaseDC failed
我正在尝试比较我的 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 似乎使用 pyscreeze 来读取屏幕上的像素值,而最有可能发生错误的地方是 pyscreeze 像素函数:
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 上 运行ning python 3.8,pyscreeze 是 0.1.25 版所以理论上一切都应该正常到目前为止,但不知何故最终崩溃了。有没有办法缓解这种情况,要么修改我的代码,甚至修改库本身,要么我的环境不适合这个操作?
嗯,我知道这不是特别有用;但对我来说,这个错误只是通过 运行 我在 3.7 而不是 3.8 上的代码修复的。但是,您不必对代码进行任何更改(除非您使用的是海象!)
在 Windows 上,这可以通过 -3.7
命令行标志完成,只要安装了 3.7
我也有这个错误,我修复了它。只需使用尝试和除外。
虽然是真的:
尝试:
x,y = pyautogui.position()
打印(pyautogui.pixel(x,y))
除了:
print("暂时无法获取像素")
鉴于您可能会多次拍摄像素,或者您可以这样做,请尝试并排除奇迹来解决任何 pyscreeze for pyautogui 问题。老实说,我不知道 pyscreeze 是怎么回事,但这对我有用。干杯
我可以像这样在 Python 3.8 上使用 pixel
函数:
try:
a = pixel(100,100)
> except:
> a = pixel(100,100)
我不知道为什么会这样,但它确实有效。
这是一个错误。您走在正确的轨道上,因为问题确实出在 pixel()
函数的这一行:
with __win32_openDC(0) as hdc
该函数使用 cyptes.windll
,它似乎不能很好地处理有时从 windll.user32.GetDC()
返回的负值,这随后在调用 windll.user32.ReleaseDC()
时创建异常。
pillow
的人员帮助查明了这个问题并提出了解决方案。
- issue 归档于
pyautogui
- issue 在 pillow 提交导致解决方案
- pending PR 在 pyscreeze 上地址
这里是 PyScreeze 和 PyAutoGUI 的维护者。这是 PyScreeze 0.1.28 中已修复的问题,因此您只需更新 运行 pip install -U pyscreeze
.
有关更多上下文,这里是报告的 GitHub 问题:https://github.com/asweigart/pyscreeze/pull/73
我正在尝试比较我的 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 似乎使用 pyscreeze 来读取屏幕上的像素值,而最有可能发生错误的地方是 pyscreeze 像素函数:
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 上 运行ning python 3.8,pyscreeze 是 0.1.25 版所以理论上一切都应该正常到目前为止,但不知何故最终崩溃了。有没有办法缓解这种情况,要么修改我的代码,甚至修改库本身,要么我的环境不适合这个操作?
嗯,我知道这不是特别有用;但对我来说,这个错误只是通过 运行 我在 3.7 而不是 3.8 上的代码修复的。但是,您不必对代码进行任何更改(除非您使用的是海象!)
在 Windows 上,这可以通过 -3.7
命令行标志完成,只要安装了 3.7
我也有这个错误,我修复了它。只需使用尝试和除外。 虽然是真的: 尝试: x,y = pyautogui.position() 打印(pyautogui.pixel(x,y)) 除了: print("暂时无法获取像素")
鉴于您可能会多次拍摄像素,或者您可以这样做,请尝试并排除奇迹来解决任何 pyscreeze for pyautogui 问题。老实说,我不知道 pyscreeze 是怎么回事,但这对我有用。干杯
我可以像这样在 Python 3.8 上使用 pixel
函数:
try:
a = pixel(100,100)
> except:
> a = pixel(100,100)
我不知道为什么会这样,但它确实有效。
这是一个错误。您走在正确的轨道上,因为问题确实出在 pixel()
函数的这一行:
with __win32_openDC(0) as hdc
该函数使用 cyptes.windll
,它似乎不能很好地处理有时从 windll.user32.GetDC()
返回的负值,这随后在调用 windll.user32.ReleaseDC()
时创建异常。
pillow
的人员帮助查明了这个问题并提出了解决方案。
- issue 归档于
pyautogui
- issue 在 pillow 提交导致解决方案
- pending PR 在 pyscreeze 上地址
这里是 PyScreeze 和 PyAutoGUI 的维护者。这是 PyScreeze 0.1.28 中已修复的问题,因此您只需更新 运行 pip install -U pyscreeze
.
有关更多上下文,这里是报告的 GitHub 问题:https://github.com/asweigart/pyscreeze/pull/73