Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Active window screenshot with Python PIL and windows API: how to deal with rounded corners?

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.

like image 918
NorthernLights Avatar asked May 14 '11 00:05

NorthernLights


1 Answers

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.

like image 80
Antonio Beamud Avatar answered Sep 21 '22 06:09

Antonio Beamud