Quickly getting the color of some pixels on the screen in Python on Windows 7

Solution 1:

Thanks to Margus' direction, I focused on getting the image before extracting the pixel information. Here's a workable solution using the Python Imaging Library (PIL), which requires 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())

I don't think it gets any simpler than that. This takes (on average) 0.1 seconds, which is a little slower than I'd like but fast enough.

As for having Python 3.x and 2.x both installed, I separated that into a new question. I'm still having some trouble with it, but it's generally working.

Solution 2:

This is better than using getpixel all the time and works faster.

import ImageGrab

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

Reference: Image.load

Solution 3:

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

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)

Solution 4:

I had this same exact problem, and solved it (in Java, in C#). The main idea behind the solution is GetPixel from screen is slow, and you can't fix that. But as you need some pixels, you can get a bunch of them all at once.

The time that it took to get 64 pixels was 98 times faster.