I'm working on a small automation tool that takes snapshots of the screen, does some template matching, and then responds accordingly. I've previously used PIL for this, but it's ImageGrab
function is limited to the main monitor, I need the option of grabbing any display device attached to the machine. After some brief Googling, I arrived at the following code as a solution.
ScreenShot Code
def capture_display():
monitors = win32api.EnumDisplayMonitors(None, None)
hwnd = monitors[1][1].handle
l,t,r,b = monitors[1][2]
w = r - l
h = b
hwndDC = win32gui.GetWindowDC(hwnd)
mfcDC = win32ui.CreateDCFromHandle(hwndDC)
saveDC = mfcDC.CreateCompatibleDC()
saveBitMap = win32ui.CreateBitmap()
saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)
saveDC.SelectObject(saveBitMap)
saveDC.BitBlt((0, 0), (w, h), mfcDC, (l, t), win32con.SRCCOPY)
saveBitMap.SaveBitmapFile(saveDC, 'screencapture.bmp')
This works remarkably well. However, it saves the image. All I need is access to the underlying pixel array in memory.
Of course, there is the option of just saving it, reloading it from disc via PIL, and then getting the pixel data, but the IO overhead on this is too great to be of any use.
Now, I'm in foreign territory with the Windows API, however, from reading on MSDN I found this:
Memory Device Contexts
It is an array of bits in memory that an application can use temporarily to store the color data for bitmaps created on a normal drawing surface. Because the bitmap is compatible with the device, a memory DC is also sometimes referred to as a compatible device context.
So, it seems like these DCs indeed store the pixel data, but I just have no idea how to access it. How do I get at that underlying pixel array?