BoboTiG / python-mss

An ultra fast cross-platform multiple screenshots module in pure Python using ctypes.
https://pypi.org/project/mss/
MIT License
1.04k stars 94 forks source link

classic theme increased performance on x5-x7 #223

Open muk-as opened 1 year ago

muk-as commented 1 year ago

General information:

Description of the warning/error

if disable windows aero(use classic theme) than performance will increased on x5-x7

Full message

with mss.mss() as sct:

    bbox = (0, 0, 1280, 720)
    log.console_time('MSS_start')
    for i in range(1000):
        screenshot = np.array(sct.grab(bbox), copy=False, order='C')
    log.console_time('MSS1_end')
    #print(screenshot.flags)
    for i in range(1000):
        screenshot = np.ascontiguousarray(sct.grab(bbox))
    log.console_time('MSS2_end')
    #print(screenshot.flags)
    for i in range(1000):
        screenshot = np.array(sct.grab(bbox))
    log.console_time('MSS3_end')

with aero

2023-01-15 21:06:37,407 | window_capture.py      ->             <module>():127 | MainThread | INFO   : [!t] MSS_start _ default _ exec_time: 2.430 ms
2023-01-15 21:06:55,844 | window_capture.py      ->             <module>():130 | MainThread | INFO   : [!t] MSS1_end _ default _ exec_time: 18437 ms
2023-01-15 21:07:14,344 | window_capture.py      ->             <module>():134 | MainThread | INFO   : [!t] MSS2_end _ default _ exec_time: 18499 ms
2023-01-15 21:07:32,763 | window_capture.py      ->             <module>():138 | MainThread | INFO   : [!t] MSS3_end _ default _ exec_time: 18418 ms

with classic theme

2023-01-15 21:08:02,949 | window_capture.py      ->             <module>():127 | MainThread | INFO   : [!t] MSS_start _ default _ exec_time: 2.263 ms
2023-01-15 21:08:05,410 | window_capture.py      ->             <module>():130 | MainThread | INFO   : [!t] MSS1_end _ default _ exec_time: 2460. ms
2023-01-15 21:08:07,895 | window_capture.py      ->             <module>():134 | MainThread | INFO   : [!t] MSS2_end _ default _ exec_time: 2484. ms
2023-01-15 21:08:11,611 | window_capture.py      ->             <module>():138 | MainThread | INFO   : [!t] MSS3_end _ default _ exec_time: 3715. ms

try tests on win10, win11 and other python versions and type results

Upvote & Fund

Fund with Polar

CTPaHHuK-HEbA commented 1 year ago

windows 10 doesn't have classic theme

BoboTiG commented 1 year ago

My naive guess would be that Aero is using a lot of blur, and so there are less way to compress pixels. It would be interesting to track the MSS code to see where the time is spent.

muk-as commented 1 year ago

right now im using this code. its a little faster than mss on my requestions. and it's doesn't care about aero. same results with classic and with aero themes

self.hwnd = win32gui.FindWindow(None, self.window_name)
def _screenshot_win(self): # cpu_avg 2.8 on 50ms sleep | 1.4 on 100ms | 1.15 on 100ms with openCV cvtColor
    # get the window image data
    wDC = win32gui.GetWindowDC(self.hwnd)
    dcObj = win32ui.CreateDCFromHandle(wDC)
    cDC = dcObj.CreateCompatibleDC()
    dataBitMap = win32ui.CreateBitmap()
    dataBitMap.CreateCompatibleBitmap(dcObj, self.w, self.h)
    cDC.SelectObject(dataBitMap)
    cDC.BitBlt((0, 0), (self.w, self.h), dcObj, (0, 0), win32con.SRCCOPY)

    # convert the raw data into a format opencv can read
    signedIntsArray = dataBitMap.GetBitmapBits(True)
    img = np.frombuffer(signedIntsArray, dtype='uint8')
    img.shape = (self.h, self.w, 4)

    # free resources
    dcObj.DeleteDC()
    cDC.DeleteDC()
    win32gui.ReleaseDC(self.hwnd, wDC)
    win32gui.DeleteObject(dataBitMap.GetHandle())

    img = cv.cvtColor(img, cv.COLOR_BGRA2BGR) # drops alpha + save C_CONTIGUOUS flag
    return img
CTPaHHuK-HEbA commented 1 year ago

My naive guess would be that Aero is using a lot of blur, and so there are less way to compress pixels. It would be interesting to track the MSS code to see where the time is spent.

I think, first source code, only copying from video memory, no compression

same results with classic and with aero themes self.hwnd = win32gui.FindWindow(None, self.window_name)

You sample capture only inside the window, not desktop? Maybe : same results with classic and with aero themes

My tests: Windows 7 Monitor 60Hz Using display styles for buttons and windows Other switch - no effect

On: ~ 20 fps Off ~ 80 fps

Regresion in this function: self.gdi32.BitBlt()

BoboTiG commented 1 year ago

Thanks for the clue @CTPaHHuK-HEbA. It seems unrelated to MSS but how Windows works under the wood: https://stackoverflow.com/q/7154574/1117028.

I do not close the issue because I hope there is some hidden API, or whatever we could leverage, to improve slightly the situation. I'm open to suggestions too :)