GoTVm
GoTVm

Reputation: 31

Python script using ImageGrab causes intermittent stuttering

Code here:

def getColor():
    return ImageGrab.grab().getpixel(position) #was mouse.position

def crash_detect():
        global running, crashed
    
    if isOnL(getColor()):
        printColor("(" + str(datetime.now().strftime("%H:%M")) + ")" + " Condition1", Fore.BLUE)
        crashed = True
        running = False

def finish_detect():
    global running

    if isInM(getColor()):
        printColor("(" + str(datetime.now().strftime("%H:%M")) + ")" + " Condition2", Fore.YELLOW)
        running = False
        killProcess() #simply kills a process using os.system(taskkill)

def handleExceptions():
    crash_detect()
    finish_detect()

while True:
    while running:
        crashed = False
        if mouse.position != position:
            mouse.position = position

        mouse.press(Button.right)
        time.sleep(random.uniform(p_duration.__getitem__(0), p_duration.__getitem__(1)))
        keyboard.press("h")
        time.sleep(random.uniform(w_duration.__getitem__(0), w_duration.__getitem__(1)))
        keyboard.release("h")
        mouse.release(Button.right)
        handleExceptions()

    if autoresume and crashed:
        crash_recovery()

isOnL and isInM are just functions that compare the color to a set of known colors.

This is part of a script that causes intermittent CPU usage spikes on my laptop; the spikes seem to happen relatively periodically, leading me to think it's because of ImageGrab's getPixel() function. Am I on the right track thinking this, or should I look for the root cause in another place?

Upvotes: 0

Views: 43

Answers (1)

GoTVm
GoTVm

Reputation: 31

Found the solution. The script no longer causes stuttering and also is much quicker to grab the pixel color. Simply replaced ImageGrab's getPixel() with a win32gui function (albeit it only works if the pixel you need to get the color from is in the active window, as far as I know).

def getColor():
    return RGBinttotuple(win32gui.GetPixel(win32gui.GetDC(win32gui.GetActiveWindow()), x, y))

def RGBinttotuple(RGBint):
    red = RGBint & 255
    green = (RGBint >> 8) & 255
    blue = (RGBint >> 16) & 255
    return (red, green, blue)

getColor now returns an RGB value in the form of an integer, so I needed to convert it before I could use it with my old code. Also, I had to swap red and blue in the RGBinttotuple function, because for some reason they were swapped from what ImageGrab was returning.

Upvotes: 0

Related Questions