LightWrath
LightWrath

Reputation: 75

Pyscreenshot loop lag display

thanks for reading.

I have a small application with a function that will take information from a configuration file. Such as K:8 and then check if that key is down. Also it will use P:255.255.255.0010.0010 then split(".") and convert to int and check if there is a pixel of RGB 255,255,255 at the location 10X 10Y.

This is on a loop and it seems to work fine, checking takes around maybe 0.2 seconds. Which is fast enough for what I need, but I do need a solution with a few checks a second. My problem is that doing this on a loop will cause a display lag. As though the displays are reduced to around 2 FPS. So wondering if anyone knows why this might be happening or what I can do to resolve it while still getting pixel checks that are within 0.3s?

Here's my function:

def conditionCheck():
    if DataHeader[0][0][:2] == "B:": #Box limits in a string, split and convert to int.
        bbox = DataHeader[0][0][2:]
        bbox = bbox.split(".")
        bboxx1 = int(bbox[0])
        bboxy1 = int(bbox[1])
        bboxx2 = int(bbox[2])
        bboxy2 = int(bbox[3])
    pixel = (pyscreenshot.grab(bbox=(bboxx1, bboxy1, bboxx2, bboxy2))).load() #Grab screen, within limits.
    cp = 0
    while cp < len(DataConditions): #cycle through config file list
        rp = 0
        conditionPass = 0
        while rp < len(DataConditions[cp]): #Cycle through list item's conditions.
            if DataConditions[cp][rp][:2] == "K:":
                if keyboard.is_pressed(DataConditions[cp][rp][2:]): #Check if key down, set pass to true
                    conditionPass = 1
                    rp += 1 #Move to check next condition.
                    print("PRESSED") #DEBUG
                    continue
                conditionPass = 0
                break
            if DataConditions[cp][rp][:2] == "P:": #pixel colour check, match = true
                pixelData = DataConditions[cp][rp][2:] #pixel data and location in one string, conv to int and split.
                pixelData = pixelData.split(".")
                pixelLocation = pixel[int(pixelData[3]), int(pixelData[4])]
                pixelData = pixelData[0], pixelData[1], pixelData[2]
                if pixelLocation == tuple(map(int, pixelData)):
                    print("PASSED PIXEL") #DEBUG
                    conditionPass = 1
                    rp += 1
                    continue
                conditionPass = 0
                break
            rp += 1
        if conditionPass == 1:
            return cp #end loop, send line of true condition (in config file)
        cp += 1
    return 0 #Return 0 if nothing found.

I'm running this on Linux and so I'm needing a solution that is cross platform/linux friendly.

Thoughts: I'm a bit of a noob so feel free to advise on other aspects. I understand I'd get faster and smoother results doing this in C but other parts of my app would be hard to achieve in C (and my knowledge is limited) so I'm try and see if this can be achieved in Python but maybe there is just too much overhead?

Thank you

Upvotes: 1

Views: 131

Answers (1)

LightWrath
LightWrath

Reputation: 75

after some time, I think I've been able to find a solution using a different plugin, but same method. As such:

def conditionCheck():
    if DataHeader[0][0][:2] == "B:": #Box limits in a string, split and convert to int.
        bbox = DataHeader[0][0][2:]
        bbox = bbox.split(".")
        #bboxx1 = int(bbox[0])
        #bboxy1 = int(bbox[1])
        #bboxx2 = int(bbox[2])
        #bboxy2 = int(bbox[3])
        monitorWindow = {"top": int(bbox[0]), "left": int(bbox[1]), "width": int(bbox[2]), "height": int(bbox[3])}
    with mss.mss() as sct: #Grab screen, within limits.
        sct_img = sct.grab(monitorWindow)
        img = Image.new("RGB", sct_img.size)
        pixels = img.load()
        for x in range(sct_img.width):
            for y in range(sct_img.height):
                pixels[x, y] = sct_img.pixel(x, y)
    cp = 0
    while cp < len(DataConditions): #cycle through config file list
        rp = 0
        conditionPass = 0
        while rp < len(DataConditions[cp]): #Cycle through list item's conditions.
            if DataConditions[cp][rp][:2] == "K:":
                if keyboard.is_pressed(DataConditions[cp][rp][2:]): #Check if key down, set pass to true
                    conditionPass = 1
                    rp += 1 #Move to check next condition.
                    print("PRESSED") #DEBUG
                    continue
                conditionPass = 0
                break
            if DataConditions[cp][rp][:2] == "P:": #pixel colour check, match = true
                pixelData = DataConditions[cp][rp][2:] #pixel data and location in one string, conv to int and split.
                pixelData = pixelData.split(".")
                pixelLocation = pixels[int(pixelData[3]), int(pixelData[4])]
                pixelData = pixelData[0], pixelData[1], pixelData[2]
                if pixelLocation == tuple(map(int, pixelData)):
                    print("PASSED PIXEL") #DEBUG
                    conditionPass = 1
                    rp += 1
                    continue
                conditionPass = 0
                break
            rp += 1
        if conditionPass == 1:
            return cp #end loop, send line of true condition (in config file)
        cp += 1
    return 0 #Return 0 if nothing found.

Upvotes: 1

Related Questions