Быстрое получение цвета некоторых пикселей на экране в Python на Windows 7 - PullRequest
9 голосов
/ 27 сентября 2010

Мне нужно получить цвет некоторых пикселей на экране или из активного окна, и мне нужно сделать это быстро . Я пытался использовать 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())

и

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())

Каждый из них занимает около 1,75 секунды. Мне нужна такая программа, чтобы она заняла не более 0,1 секунды. Что делает это так медленно?

Я работаю с Python 3.x и Windows 7. Если ваше решение требует использования Python 2.x, пожалуйста, свяжите меня со статьей, показывающей, как установить Python 3.x и 2.x обеими. Я посмотрел, но не мог понять, как это сделать.

Спасибо!

Ответы [ 4 ]

9 голосов
/ 28 сентября 2010

Благодаря руководству Маргуса я сосредоточился на получении изображения перед извлечением информации о пикселях.Вот работоспособное решение, использующее 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())

Я не думаю, что это становится проще, чем это.Это занимает (в среднем) 0,1 секунды, что немного медленнее, чем хотелось бы, но достаточно быстро.

Что касается установки обоих Python 3.x и 2.x, я разделил это на новый вопрос .У меня все еще есть некоторые проблемы с этим, но это вообще работает.

7 голосов
/ 12 июня 2011

Это лучше, чем использовать 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]

Ссылка: Image.load

3 голосов
/ 30 августа 2013

Отключение композиции рабочего стола Windows ускоряет чтение пикселей A LOT .

Компьютер -> Свойства -> Дополнительные параметры системы -> Производительность -> Композиция рабочего стола [] (предупреждение отключает эффекты прозрачности Windows)

Python 2.7 (должен быть таким же для 3.x)

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

AutoIt для сравнения

$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)
2 голосов
/ 27 сентября 2010

У меня была та же самая проблема, и я решил ее ( в Java , в C # ).Основная идея решения заключается в том, что GetPixel с экрана работает медленно, и вы не можете это исправить.Но так как вам нужно несколько пикселей, вы можете получить их все сразу.

Время, необходимое для получения 64 пикселей, было в 98 раз быстрее.

...