Active window screenshot with Python PIL and windo

2019-03-24 05:55发布

问题:

For this project, I'm taking screenshots with the Windows API (to deal with multi-screens) and convert it to a PIL image; then I add a shadow around the window if wanted.

My problem is, the screenshot is actually of the window's rectangle; meaning I capture the background behind it around rounded-corners and I don't want that. I googled quite a bit and found docs and tuts around transparency, and I'm guessing I should find a way to get the shape of the window in order to make it a mask that I would apply to the (rectangle) image i've got. But I found noway to get that mask. Could any one help?

Below is my code:

hwnd = win32gui.GetForegroundWindow()

l, t, r, b = win32gui.GetWindowRect(hwnd)
w = r - l
h = b - t

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,  (0, 0),  win32con.SRCCOPY)

#add cursor
if showcursor:
    curFlags, curH, (curX, curY) = win32gui.GetCursorInfo()
    saveDC.DrawIcon((curX, curY), curH)

#load into PIL image
"""http://stackoverflow.com/questions/4199497/image-frombuffer-with-16-bit-image-data"""
bmpinfo = saveBitMap.GetInfo()
bmpstr = saveBitMap.GetBitmapBits(True)
im = Image.frombuffer(
    'RGB',
    (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
    bmpstr, 'raw', 'BGRX', 0, 1)

win32gui.DeleteObject(saveBitMap.GetHandle())
saveDC.DeleteDC()
mfcDC.DeleteDC()
win32gui.ReleaseDC(hwnd, hwndDC)

return im

Below is a slightly magnified screenshot of a window above a blue background:

As you can see there are blue corners that shouldn't be there.

回答1:

Why not use a Edge detection algorithm (f.e. Prewitt or Sobel) to detect the window edge, you only need to set the alpha channel to the pixels between the image limits and the window edge limits.