16

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.

martineau
  • 119,623
  • 25
  • 170
  • 301
NorthernLights
  • 193
  • 1
  • 10
  • I still couldn't find a solution. Anybody? – NorthernLights May 22 '11 at 02:32
  • 3
    In fact, I have never found a software handling window-capture successfully, even for SnippingTool.exe offerred by MicroSoft. Try Cutting 2 pixels, or making that 2 pixels of pure black/white. if u want cut the exactly shape , reading MS doc: window corner shape is defined in system.RadiusX/RadiusY http://msdn.microsoft.com/en-us/library/system.windows.shapes.rectangle.radiusy.aspx#Y0 – fanlix May 24 '12 at 13:42
  • Similar question? http://stackoverflow.com/questions/2224220/win32-how-to-make-drop-shadow-honor-non-rectangular-layered-window – notbad.jpeg Jun 16 '12 at 19:25

1 Answers1

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.

Antonio Beamud
  • 2,281
  • 1
  • 15
  • 26