Найти - Пользователи
Полная версия: Быстрое получение цвета пикселя с экрана
Начало » Python для новичков » Быстрое получение цвета пикселя с экрана
1 2
lllNF
Нужно как можно быстрее получать информацию о цвете пикселя с экрана.
Благодаря каким библиотекам это можно реализовать? Желательно с примером кода. Спасибо.

Пока что пробую pyautogui.pixel() но он слишком медленный вот сам код

 import time
import pyautogui
from pynput import keyboard
pressD = False
pressF = False
pressJ = False
pressK = False
RUN = True
while RUN:
    #D
    colorD = pyautogui.pixel(210,610) #Получение цвета пикселя
    print("colorD = ",colorD[0]) #Значение RED канала пикселя
    if colorD[0] > 230:
        #спам клавиши "d"
        keyboard.Controller().press('d')
        pressD = True
        print("'D' Down")
    else:
        if pressD:
        #прекращение спама
            keyboard.Controller().release('d')
            pressD = False
            print("'D' UP")
    #F
    colorF = pyautogui.pixel(310,610) #Получение цвета пикселя
    print("color = ",colorF[2]) #Значение BLUE канала пикселя
    if colorF[2] > 230:
        #спам клавиши "f"
        keyboard.Controller().press('f')
        pressF = True
        print("'F' Down")
    else:
        if pressF:
        #прекращение спама
            keyboard.Controller().release('f')
            pressF = False
            print("'F' UP")
    #J
    colorJ = pyautogui.pixel(410,610) #Получение цвета пикселя
    print("color = ",colorJ[2]) #Значение BLUE канала пикселя
    if colorJ[2] > 230:
        #спам клавиши "j"
        keyboard.Controller().press('j')
        pressJ = True
        print("'J' Down")
    else:
        if pressJ:
        #прекращение спама
            keyboard.Controller().release('j')
            pressJ = False
            print("'J' UP")
    #K
    colorK = pyautogui.pixel(510,610) #Получение цвета пикселя
    print("color = ",colorK[0]) #Значение RED канала пикселя
    if colorK[0] > 230:
        #спам клавиши "k"
        keyboard.Controller().press('k')
        pressK = True
        print("'K' Down")
    else:
        if pressK:
            #прекращение спама
            keyboard.Controller().release('k')
            pressK = False
            print("'K' UP")

Код спамит клавиши D,F,J,K при правильном цвете соответствующих пикселей

Если быть точным, то мне нужно получение цвета 4 пикселей экрана не реже чем 60 раз в секунду (Суммарно в секунду не менее 240 значений)
doza_and
lllNF
но он слишком медленный
С чего вы решили что он медленный? Где код по которому вы сделали вывод что он медленный?

ps
Если надо быстро обрабатывать картинку, то практически никогда не работают с отдельными пикселами даже на С не говоря уже о питоне у которого просто циклы в сотни раз медленнее.
PEHDOM
lllNF код в студию потому как даже в pyautogui есть несколько способов получить цвет пиксела.
lllNF
Где код по которому вы сделали вывод что он медленный?
 import time
import pyautogui
from pynput import keyboard
pressD = False
pressF = False
pressJ = False
pressK = False
RUN = True
while RUN:
    #D
    colorD = pyautogui.pixel(210,610) #Получение цвета пикселя
    print("colorD = ",colorD[0]) #Значение RED канала пикселя
    if colorD[0] > 230:
        #спам клавиши "d"
        keyboard.Controller().press('d')
        pressD = True
        print("'D' Down")
    else:
        if pressD:
        #прекращение спама
            keyboard.Controller().release('d')
            pressD = False
            print("'D' UP")
    #F
    colorF = pyautogui.pixel(310,610) #Получение цвета пикселя
    print("color = ",colorF[2]) #Значение BLUE канала пикселя
    if colorF[2] > 230:
        #спам клавиши "f"
        keyboard.Controller().press('f')
        pressF = True
        print("'F' Down")
    else:
        if pressF:
        #прекращение спама
            keyboard.Controller().release('f')
            pressF = False
            print("'F' UP")
    #J
    colorJ = pyautogui.pixel(410,610) #Получение цвета пикселя
    print("color = ",colorJ[2]) #Значение BLUE канала пикселя
    if colorJ[2] > 230:
        #спам клавиши "j"
        keyboard.Controller().press('j')
        pressJ = True
        print("'J' Down")
    else:
        if pressJ:
        #прекращение спама
            keyboard.Controller().release('j')
            pressJ = False
            print("'J' UP")
    #K
    colorK = pyautogui.pixel(510,610) #Получение цвета пикселя
    print("color = ",colorK[0]) #Значение RED канала пикселя
    if colorK[0] > 230:
        #спам клавиши "k"
        keyboard.Controller().press('k')
        pressK = True
        print("'K' Down")
    else:
        if pressK:
            #прекращение спама
            keyboard.Controller().release('k')
            pressK = False
            print("'K' UP")
PEHDOM
lllNF а у вас часом не венда? если венда то таки да он может работать медленно. Начнем с того что что у самого pyautogui нет метода pixel(), оно берет его из pyscreeze
 ....
try:
    import pyscreeze
    from pyscreeze import (center, grab, locate, locateAll, locateAllOnScreen,
        locateCenterOnScreen, locateOnScreen, pixel, pixelMatchesColor,
screenshot)
...
источник https://github.com/asweigart/pyautogui/blob/master/pyautogui/__init__.py
смотрим исходники pyscreeze https://github.com/asweigart/pyscreeze/blob/master/pyscreeze/__init__.py
 ....
def pixel(x, y):
    if sys.platform == 'win32':
        # On Windows, calling GetDC() and GetPixel() is twice as fast as using our screenshot() function.
        hdc = windll.user32.GetDC(0)
        color = windll.gdi32.GetPixel(hdc, x, y)
        # color is in the format 0xbbggrr https://msdn.microsoft.com/en-us/library/windows/desktop/dd183449(v=vs.85).aspx
        r = color % 256
        g = (color // 256) % 256
        b = color // (256 ** 2)
        return (r, g, b)
    else:
return screenshot().getpixel((x, y))
...
а у венды почемуто начмная с висты и выше с вклченным Windows Desktop Composition, GetPixel работает ну просто очень медленно. Хотя в коментах написано что GetPixel() работает в два раза быстрее чем screenshot().getpixel()
ps обсуждение сабжа на стекверфлов
https://stackoverflow.com/questions/3800458/quickly-getting-the-color-of-some-pixels-on-the-screen-in-python-on-windows-7
хотя ХЗ, вроде не так уж и медленно 0.003 сек у меня, по крайней мере
lllNF
PEHDOM
lllNF а у вас часом не венда? если венда то таки да он может работать медленно.

Хорошо буду знать. Но есть ли способ более быстрого получения цвета пикселя для python 3.x?
PEHDOM
lllNF
Но есть ли способ более быстрого получения цвета пикселя для python 3.x?
давайте для начала все же определимся с вашей скоростью, с чего вы взяли что оно работает медленно? Имхо 0,003 секунды вполне достаточно для любого бота, или тогда хотябы выложите сколько у вас занимает времени эта процедура.
PS мда забыл что сам всю эту фигню отключаю, вобщем получение одного пиксела Гетпикселом:
тема Windows Aero с включенной композицией 0.02 сек
тема Windows Aero с выключенной композицией 0.004 сек

Всеравно две сотых секунды достаточно быстро как по мне, если вам не нужно попиксельно перебирать весь рабочий стол.
PEHDOM
lllNF
. Но есть ли способ более быстрого получения цвета пикселя для python 3.x?
Это неправильный вопрос, все зависит от задачи, если вам нужно таки один пиксел то всежи имхо быстрее чем GetPixel сделать это весьма трудно. Другое дело если нужно найти какойто пиксел на экране или перебрать несколько пикселов, тогда имеет смысл сделать скриншот и уже работать с ним. Например на выполнение PIL.ImageGrab.grab() уходит теже 0.02 секунды, но потом вы уже не теряете время, а просто перебиаете пикселы что вам нужно.
На одном пикселе разницы никакой, но напмриер на 4-х разница уже в 4 раза, так как на PIL.ImageGrab.grab() у вас уйдет 0.2 секунды, а на всю остальную математику десятытысячные доли, в тоже время на каждый GetPixel() у вас будет уходить по 0.02 секунды, а это уже почти 0.1 секунды.
В данном случае, не ГетПиксел медленный, а архитектура неправильная
lllNF
PEHDOM
Да, для простого получения пикселя это занимает 0.003 сек. но в самом коде помимо этого есть много других команд, они тоже занимают время. Сверху оригинальных код, на одно выполнение которого уходит ~0.06 сек, а это много.

Как можно оптимизировать этот код? Я просто в этом деле ещё совсем зеленый
vic57
lllNF
Как можно оптимизировать этот код?
попробуй QImage, там функции сишные
http://doc.qt.io/qt-5/qimage.html#pixel-1
типа так
 >>>from PyQt5 import Qt
>>> img = Qt.QImage(100,100,Qt.QImage.Format_RGB32)
>>> img.fill(Qt.QColor(100,150,200))
>>> pix = img.pixel(10,10)
>>> r,g,b = Qt.qRed(pix),Qt.qGreen(pix),Qt.qBlue(pix)
>>> r,g,b
(100, 150, 200)
>>> 
я бы через ctypes сделал, намного быстрее с однородными массивами работает

This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB