使用Python PIL和Windows API的活动窗口屏幕截图:如何处理圆角?

发布于 2024-11-07 19:51:06 字数 1482 浏览 4 评论 0原文

对于此项目,我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天荒地未老 2024-11-14 19:51:06

为什么不使用边缘检测算法(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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文