如何在 OSX 中访问 NSWindow 的像素缓冲区?

发布于 2024-10-27 17:08:41 字数 167 浏览 0 评论 0原文

我正在寻找一种方法来获取像 CamTwist“桌面+”功能这样的窗口内容。这可以抓取任何窗口,即使它位于后台。

Apple 的 OpenGLScreenCapture 示例展示了如何从主屏幕而不是从隐藏表面进行捕获。

知道 CamTwist 如何访问 NSWindow 的像素缓冲区吗?

I'm looking for a way to grab the contents of a window like CamTwist 'Desktop+' feature. This can grab any window, even when its in the background.

Apple's OpenGLScreenCapture sample shows how to capture from the main screen but not from hidden surfaces.

Any idea how CamTwist gets access to the pixel buffer of an NSWindow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(2

待"谢繁草 2024-11-03 17:08:41

AFAIK,官方 API 可以作为 CoreGraphics 的一部分在 CGWindow.h 中找到:

/* Create an image containing a composite of the specified set of windows
   contained within a rectangular area. The set of windows is specified
   using options from `CGWindowListOption', along with an optional
   additional window ID.

   The windows list options are:

   --- kCGWindowListOptionAll, kCGWindowListOptionOnScreenOnly: Use all
   on-screen windows in this user session to construct the image. The
   parameter `windowID' should be `kCGNullWindowID'.

   --- kCGWindowListOptionOnScreenAboveWindow: Use all on-screen windows in
   this user session above the window specified by `windowID', ordered from
   front to back, to construct the image. To include the window specified by
   `windowID', add the flag `kCGWindowListOptionIncludingWindow'.

   --- kCGWindowListOptionOnScreenBelowWindow: Use all on-screen windows in
   this user session below the window specified by `windowID', ordered from
   front to back, to construct the image. To include the window specified by
   `windowID', add the flag `kCGWindowListOptionIncludingWindow'.

   --- kCGWindowListOptionIncludingWindow: Use only the window specified by
   `windowID' to construct the image.

   The parameter `screenBounds' specifies the rectangle in screen space
   (origin at the upper-left; y-value increasing downward). Setting
   `screenBounds' to `CGRectInfinite' will include all the windows on the
   entire desktop. Setting `screenBounds' to `CGRectNull' will use the
   bounding box of the specified windows as the screen space rectangle.

break

   /* The parameter `imageOptions' allows you to specify whether the window
   frame ornamentation, such as a shadow or similar effect, should be
   included or excluded in the bounds calculation when `CGRectNull' is
   specified for the window bounds.

   If no windows meet the specified criteria, or the windows can't be read,
   then a transparent black image will be returned.

   Any on-screen window with sharing type `kCGWindowSharingNone' will not
   be included in the image.

   This function returns NULL if the caller is not running within a Quartz
   GUI session or the window server is disabled. */

CG_EXTERN CGImageRef CGWindowListCreateImage(CGRect screenBounds,
  CGWindowListOption listOption, CGWindowID windowID,
  CGWindowImageOption imageOption)
  CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);

/* Create an image containing a composite of the specified set of windows
   contained within a rectangular area à la `CGWindowListCreateImage'. The
   set of windows is specified by `windowArray', an array of window IDs. */

CG_EXTERN CGImageRef CGWindowListCreateImageFromArray(CGRect screenBounds,
  CFArrayRef windowArray, CGWindowImageOption imageOption)
  CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);

抱歉,无法找到 Apple 网站上文档的链接。但是,他们确实在 Son of Grab< 中提供了示例代码/a>.

AFAIK, the official APIs can be found in CGWindow.h as part of CoreGraphics:

/* Create an image containing a composite of the specified set of windows
   contained within a rectangular area. The set of windows is specified
   using options from `CGWindowListOption', along with an optional
   additional window ID.

   The windows list options are:

   --- kCGWindowListOptionAll, kCGWindowListOptionOnScreenOnly: Use all
   on-screen windows in this user session to construct the image. The
   parameter `windowID' should be `kCGNullWindowID'.

   --- kCGWindowListOptionOnScreenAboveWindow: Use all on-screen windows in
   this user session above the window specified by `windowID', ordered from
   front to back, to construct the image. To include the window specified by
   `windowID', add the flag `kCGWindowListOptionIncludingWindow'.

   --- kCGWindowListOptionOnScreenBelowWindow: Use all on-screen windows in
   this user session below the window specified by `windowID', ordered from
   front to back, to construct the image. To include the window specified by
   `windowID', add the flag `kCGWindowListOptionIncludingWindow'.

   --- kCGWindowListOptionIncludingWindow: Use only the window specified by
   `windowID' to construct the image.

   The parameter `screenBounds' specifies the rectangle in screen space
   (origin at the upper-left; y-value increasing downward). Setting
   `screenBounds' to `CGRectInfinite' will include all the windows on the
   entire desktop. Setting `screenBounds' to `CGRectNull' will use the
   bounding box of the specified windows as the screen space rectangle.

break

   /* The parameter `imageOptions' allows you to specify whether the window
   frame ornamentation, such as a shadow or similar effect, should be
   included or excluded in the bounds calculation when `CGRectNull' is
   specified for the window bounds.

   If no windows meet the specified criteria, or the windows can't be read,
   then a transparent black image will be returned.

   Any on-screen window with sharing type `kCGWindowSharingNone' will not
   be included in the image.

   This function returns NULL if the caller is not running within a Quartz
   GUI session or the window server is disabled. */

CG_EXTERN CGImageRef CGWindowListCreateImage(CGRect screenBounds,
  CGWindowListOption listOption, CGWindowID windowID,
  CGWindowImageOption imageOption)
  CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);

/* Create an image containing a composite of the specified set of windows
   contained within a rectangular area à la `CGWindowListCreateImage'. The
   set of windows is specified by `windowArray', an array of window IDs. */

CG_EXTERN CGImageRef CGWindowListCreateImageFromArray(CGRect screenBounds,
  CFArrayRef windowArray, CGWindowImageOption imageOption)
  CG_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA);

Sorry, could not find a link to the documentation on Apple's site. However, they do appear to have sample code in Son of Grab.

微暖i 2024-11-03 17:08:41

AFAIK 你不能使用官方 API 来做到这一点。当然这是可能的,否则苹果怎么实现Exposé呢? 在这里您可以找到人们通过对Apple代码进行逆向工程创建的标头;使用它需要您自担风险(作为私有 API,任何这些调用都可能会随着 Apple 的任何发布而随时更改,且不会发出任何通知),并且如果您正在使用它,不要指望 Apple 会让您进入他们的 App Store :-) 如您所见,您可以使用此 API 获取所有应用程序的所有窗口(包括隐藏窗口)的列表,甚至可以操作它们;尽管您真正被允许执行的操作可能取决于您的应用程序权限。 这里是代码< /a> 展示了如何使用这个私有 API 来捕获您喜欢的任何窗口的内容。请注意,根据操作系统版本,代码的工作方式有所不同,有一种方法可以在 10.5 之前执行此操作,也可以在 10.5 之后执行此操作,因此,如果您的目标是较旧的系统,请确保同时实现这两种方法。顺便说一句,用于真正获取图像的最终 API 调用不是私有的,它们可以在官方 SDK 标头中找到,只有如何获取对不属于当前进程的窗口的引用的方式才是私有的。

更新:从10.5开始,从窗口服务器复制WindowID的重要功能已被Apple公开;所以它不再是私有 API。然而,在 10.5 之前就已经可以检索这些 WindowID,但当时标头尚未公开,而且在逆向工程标头中找到的所有函数仍未公开。

AFAIK you cannot do that using official API. Of course this is possible, otherwise how would Apple implement Exposé otherwise? Here you can find a header that people have created by reverse engineering Apple's code; use it at your own risk (being a private API, any of those calls might change with any release from Apple at any time and without any notification) and don't expect Apple will let you into their App Store, if you are using it :-) As you can see, you can use this API to get a list of all windows (including hidden ones) of all applications and you can even manipulate them; though what you are really allowed to do may depend on your app privileges. And here's code that shows how you can use this private API, to capture the content of any window you like. Please note that the code works differently depending on OS version, there is a way how to do it pre-10.5 and how to do it post-10.5, so if you are targeting older systems, be sure you also implement both ways. The final API calls being used to really get the image are not private, BTW, they are found in the official SDK headers, only the way how you get a reference to a window that does not belong to your current process is private.

Update: Starting with 10.5 the important function to copy WindowIDs from the window server has been made public by Apple; so it is not private API any longer. However, it was already possible to retrieve those WindowIDs prior to 10.5, but the header hasn't been public at that time and still not all functions found in the reversed engineered header have been made public, yet.

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