使用Python PIL和Windows API的活动窗口屏幕截图:如何处理圆角?
对于此项目,我使用 Windows API 截取屏幕截图(以处理多屏问题) ) 并将其转换为 PIL 图像;然后,如果需要的话,我可以在窗户周围添加阴影。
我的问题是,屏幕截图实际上是窗口的矩形;这意味着我捕捉了圆角周围的背景,但我不希望这样。我在谷歌上搜索了很多,找到了有关透明度的文档和图解,我猜我应该找到一种方法来获取窗口的形状,以便将其用作我将应用于我已经的(矩形)图像的蒙版得到。但我发现找不到那个面具。有人可以帮忙吗?
下面是我的代码:
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
下面是蓝色背景上方窗口的稍微放大的屏幕截图:
As你可以看到有一些不应该存在的蓝色角。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么不使用边缘检测算法(fe Prewitt 或 Sobel)来检测窗口边缘,您只需需要将 Alpha 通道设置为图像限制和窗口边缘限制之间的像素。
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.