【问题标题】:Grab a screenshot of an obscured window抓取一个被遮挡的窗口的屏幕截图
【发布时间】:2012-08-13 02:38:10
【问题描述】:
我正在使用 CGWindowListCreateImage 来获取屏幕截图。我正在尝试获取一个特定的窗口,我知道它的 windowID。这是我正在使用的代码,但它似乎总是占据整个屏幕,包括所有窗口。
CGImageRef windowImage = CGWindowListCreateImage(
CGRectNull,
kCGWindowListOptionOnScreenOnly,
windowID,
kCGWindowImageBoundsIgnoreFraming);
我做错了什么?
【问题讨论】:
标签:
objective-c
macos
quartz-graphics
【解决方案1】:
您要求它抓取整个屏幕,包括所有窗口,因此您得到的正是您所要求的。看the documentation:
窗口选项
描述哪些窗口包含在
图片。典型选项让您选择所有窗口或上方的窗口或
在 windowID 参数中指定的窗口下方。更多
信息,请参阅“窗口列表选项常量”。
对于这个值,您传递的是kCGWindowListOptionOnScreenOnly,这意味着:
列出当前在屏幕上的所有窗口。窗户按从前到后的顺序返回。使用此选项检索列表时,relativeToWindow 参数应设置为 kCGNullWindowID。
从技术上讲,使用 windowID 传递这个选项甚至是不合法的,但如果你这样做了,Quartz 很好,它会忽略你的 ID。
如果您希望您的屏幕截图绑定到窗口的屏幕矩形,您需要传递它,而不是 CGRectNull。如果您想要隐藏的窗口而不是它前面的窗口,请使用kCGWindowListOptionOnScreenBelowWindow | kCGWindowListOptionIncludingWindow 作为您的选项。
【解决方案2】:
我也遇到了同样的问题。记录了kCGWindowImageBoundsIgnoreFraming 选项以允许指定CGRectNull:
当请求的捕获矩形为CGRectNull时,使用该选项只捕获窗口区域,不捕获任何窗口框架效果占用的区域。
但对我来说,我不得不将kCGWindowListOptionIncludingWindow 指定为唯一的窗口选项。这与文档所说的有些矛盾:
您必须将此选项与kCGWindowListOptionOnScreenAboveWindow 或kCGWindowListOptionOnScreenBelowWindow 选项结合使用才能检索有意义的结果。
但如果我听从了这个建议,屏幕截图始终是整个屏幕。总而言之,以下内容按预期对我有用:
CGImageRef windowImage = CGWindowListCreateImage(
CGRectNull,
kCGWindowListOptionIncludingWindow,
windowID,
kCGWindowImageBoundsIgnoreFraming);
(或者几乎与预期一样 - 屏幕截图仍然包含窗口的标题栏,我希望 kCGWindowImageBoundsIgnoreFraming 意味着窗口的标题栏也被跳过)。