抓取被遮挡窗口的屏幕截图

3

我正在使用CGWindowListCreateImage来获取屏幕截图。我想要抓取一个特定的窗口,我知道它的窗口ID。这是我正在使用的代码,但它似乎总是抓取整个屏幕,包括所有窗口。

CGImageRef windowImage = CGWindowListCreateImage(
      CGRectNull, 
      kCGWindowListOptionOnScreenOnly, 
      windowID, 
      kCGWindowImageBoundsIgnoreFraming);

我做错了什么?

2个回答

5
您正在请求捕获整个屏幕,包括所有窗口,因此您得到了您所要求的内容。请参阅文档

windowOption

描述要包含在图像中的窗口的选项。典型的选项让您选择所有窗口或窗口上方或下方的窗口。有关更多信息,请参见“窗口列表选项常量”。

对于这个值,您正在传递 kCGWindowListOptionOnScreenOnly,这意味着:

列出所有当前在屏幕上的窗口。窗口按从前到后的顺序返回。使用此选项检索列表时,relativeToWindow参数应设置为kCGNullWindowID。

从技术上讲,甚至不合法将此选项与windowID一起使用,但如果您这样做,Quartz会很好地忽略您的ID。
如果您想让您的截图限制在窗口的屏幕矩形内,您需要传递该矩形而不是CGRectNull。如果您想要遮挡的窗口而不是它前面的内容,请使用kCGWindowListOptionOnScreenBelowWindow | kCGWindowListOptionIncludingWindow作为您的选项。

1
我刚刚遇到了同样的问题。文档中已经记录了kCGWindowImageBoundsIgnoreFraming选项允许指定一个CGRectNull

当请求的捕获矩形为CGRectNull时,使用此选项仅捕获窗口区域,不捕获任何窗口装饰效果占用的区域。

但对我来说,我必须将kCGWindowListOptionIncludingWindow指定为唯一的窗口选项。这有点与文档上说的相矛盾:

您必须将此选项与kCGWindowListOptionOnScreenAboveWindowkCGWindowListOptionOnScreenBelowWindow选项结合使用,以检索有意义的结果。

但是,如果我按照那个建议操作,截屏总是整个屏幕。因此,总结一下,以下内容对我有效:
CGImageRef windowImage = CGWindowListCreateImage(
      CGRectNull, 
      kCGWindowListOptionIncludingWindow, 
      windowID, 
      kCGWindowImageBoundsIgnoreFraming);

(或者几乎可以预料到的是 - 截图仍然包含窗口的标题栏,我希望kCGWindowImageBoundsIgnoreFraming意味着窗口的标题栏也被跳过。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接