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

前端 未结 4 910
说谎
说谎 2020-12-04 22:44

I need to get the color of some pixels on the screen or from the active window, and I need to do so quickly. I\'ve tried using win32gui and ctypes/

相关标签:
4条回答
  • 2020-12-04 23:20

    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

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-12-04 23:23

    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.

    0 讨论(0)
  • 2020-12-04 23:33

    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)
    
    0 讨论(0)
提交回复
热议问题