Question

I'm trying to use the pywin32 module to get the bitmap of a window's client area. Using the exact code from this question I am able to get the bitmap of the entire desktop. Specifically, when I look at the bits returned, there are 4*(desktop-pixels) number of entries. However, when I try to do something similar for a window or client area, I get less entries returned then there are pixels. My code for getting the window bitmap is below. However, I have tried several variations on it. For example, replacing the window parts with the client area, setting the (nXSrc, nYSrc) to zero, etc. Any suggestions on what I might be doing wrong? Thank you much!

Code:

windowName = "MyProcessWindow"
windowHandle = win32ui.FindWindow(None, windowName).GetSafeHwnd()
windowRectangle = win32gui.GetWindowRect(windowHandle)
width = windowRectangle[2]-windowRectangle[0]
height = windowRectangle[3]-windowRectangle[1]
win32gui.SetForegroundWindow(windowHandle)
windowDeviceContext = win32gui.GetWindowDC(windowHandle)
deviceContextObject = win32ui.CreateDCFromHandle(windowDeviceContext)
compatibleDeviceContext = deviceContextObject.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(compatibleDeviceContext, width, height)
compatibleDeviceContext.SelectObject(dataBitMap)
compatibleDeviceContext.BitBlt((0,0), (width, height), deviceContextObject, (windowRectangle[0],windowRectangle[1]), win32con.SRCCOPY)
info = dataBitMap.GetInfo()
bits = dataBitMap.GetBitmapBits(False)
print info
print len(bits)
print (width*height)

Print results:

{'bmType': 0, 'bmWidthBytes': 92, 'bmHeight': 526, 'bmBitsPixel': 1, 'bmPlanes': 1, 'bmWidth': 728}
48392
382928
Was it helpful?

Solution

I think the problem is this:

dataBitMap.CreateCompatibleBitmap(compatibleDeviceContext, width, height)

You want to create a bitmap that's compatible with the source DC, which has the appropriate color depth and other features. Then you can select that into the target DC, which will give it the appropriate color depth, size, and other features.

Instead, you're creating one that's compatible with the target DC, which at this point is a 1x1 black&white DC, as explained in the CreateCompatibleDC docs. Then you select that into the target DC, leaving it exactly as it started.

That's why you end up with a bitmap with 1 plane of 1bpp.

See the Capturing a Image sample (in C, and horrible C at that, but hopefully you can follow it) for an example of how to do it. But I believe this is the only step you're doing wrong.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top