在Windows 7上用Python快速获取屏幕上某些像素的颜色

dln*_*385 11 python screen pixel colors windows-7

我需要在屏幕上或从活动窗口获取某些像素的颜色,我需要快速完成.我尝试过使用win32gui和ctypes/windll,但它们太慢了.这些程序中的每一个都获得100像素的颜色:

import win32gui
import time
time.clock()
for y in range(0, 100, 10):
    for x in range(0, 100, 10):
        color = win32gui.GetPixel(win32gui.GetDC(win32gui.GetActiveWindow()), x , y)
print(time.clock())
Run Code Online (Sandbox Code Playgroud)

from ctypes import windll
import time
time.clock()
hdc = windll.user32.GetDC(0)
for y in range(0, 100, 10):
    for x in range(0, 100, 10):
        color = windll.gdi32.GetPixel(hdc, x, y)
print(time.clock())
Run Code Online (Sandbox Code Playgroud)

每个都需要大约1.75秒.我需要这样的程序花费不到0.1秒.是什么让它如此缓慢?

我正在使用Python 3.x和Windows 7.如果您的解决方案需要我使用Python 2.x,请链接到一篇文章,展示如何安装Python 3.x和2.x. 我看了,但无法弄清楚如何做到这一点.

谢谢!

dln*_*385 9

感谢Margus的指导,我专注于在提取像素信息之前获取图像.这是一个使用Python Imaging Library(PIL)的可行解决方案,它需要Python 2.x.

import ImageGrab
import time
time.clock()
image = ImageGrab.grab()
for y in range(0, 100, 10):
    for x in range(0, 100, 10):
        color = image.getpixel((x, y))
print(time.clock())
Run Code Online (Sandbox Code Playgroud)

我不认为这比那更简单.这需要(平均)0.1秒,这比我想要的要慢一点但足够快.

至于安装了Python 3.x和2.x,我把它分成了一个新问题.我仍然遇到一些麻烦,但它通常都有效.


Ole*_*pin 7

这比使用getpixel所有时间更好,并且工作得更快.

import ImageGrab

px=ImageGrab.grab().load()
for y in range(0,100,10):
    for x in range(0,100,10):
        color=px[x,y]
Run Code Online (Sandbox Code Playgroud)

参考:Image.load

  • ImageGrab 仅适用于 Windows。 (2认同)

Jaa*_*kko 6

Disabling Windows Desktop Composition speeds pixel up reading A LOT.

Computer -> Properties -> Advanced system settings -> Performance -> desktop composition [ ] (warning this disables Windows's transparency effects)

Python 2.7 (Should be same for 3.x)

win32gui.GetPixel()     #1.75s => 20ms
windll.gdi32.GetPixel() #1.75s => 3ms (fastest)
image.getpixel()        # 0.1s => 50ms
px[]                    # 0.1s => 50ms
Run Code Online (Sandbox Code Playgroud)

AutoIt for comparison

$timer = TimerInit()

For $x = 0 To 100 Step 10
    For $y = 0 To 100 Step 10
        PixelGetColor($x,$y) ;slow => 1ms
    Next
Next

ConsoleWrite("Time: " & TimerDiff($timer)/1000 & @CRLF)
Run Code Online (Sandbox Code Playgroud)


Mar*_*gus 3

我遇到了同样的问题,并解决了它(在 Java 中在 C# 中)。该解决方案背后的主要思想是从屏幕获取像素很慢,并且您无法修复它。但当您需要一些像素时,您可以一次获得一堆像素。

获得 64 像素所需的时间快了 98 倍。