Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using screencapture with win32gui, memory leak occurs #2171

Open
muhaha211 opened this issue Jan 29, 2024 · 1 comment
Open

When using screencapture with win32gui, memory leak occurs #2171

muhaha211 opened this issue Jan 29, 2024 · 1 comment

Comments

@muhaha211
Copy link

import numpy as np
import win32gui, win32ui, win32con
import time 
import cv2
import psutil

def memory_usage(message: str = 'debug'):
    # current process RAM usage
    p = psutil.Process()
    rss = p.memory_info().rss / 2 ** 20 # Bytes to MB
    print(f"[{message}] memory usage: {rss: 10.5f} MB")

class ImageSearch:


    # constructor
    def __init__(self, windowx=0, windowy=0, windowr=0):
        self.hwnd = win32gui.GetDesktopWindow()  # Get the desktop window handle

    def screencapture(self):
        # Get the window size
        window_rect = win32gui.GetWindowRect(self.hwnd)
        self.left = window_rect[0]
        self.top = window_rect[1]
        self.weight = window_rect[2] - window_rect[0]
        self.height = window_rect[3] - window_rect[1]

        # Get the window image data
        wDC = win32gui.GetWindowDC(self.hwnd)
        dcObj = win32ui.CreateDCFromHandle(wDC)
        cDC = dcObj.CreateCompatibleDC()
        dataBitMap = win32ui.CreateBitmap()
        dataBitMap.CreateCompatibleBitmap(dcObj, self.weight, self.height)
        cDC.SelectObject(dataBitMap)
        cDC.BitBlt((0, 0), (self.weight, self.height), dcObj, (self.left, self.top), 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.height, self.weight, 4)

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

        img = img[..., :3]
        img = np.ascontiguousarray(img)

        return img

a = ImageSearch()
while True:
    memory_usage('#1')
    abc = a.screencapture()

Python 3.10.11, pywin306 on windows10.
The code causes memory to keep increasing over time when executed. It appears that something in the win32 capture method is causing a leak, but I'm not sure of the exact cause or solution. Despite searching online, there doesn't seem to be an obvious issue with the code. Is there a solution available?

@mhammond
Copy link
Owner

You'd need to narrow you code down even further and work out which pywin32 function is actually causing the leak. Once identified a fix should be fairly easy but will require a new build of pywin32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants