Cocoa 如何在OSX中访问NSX窗口的像素缓冲区?

Cocoa 如何在OSX中访问NSX窗口的像素缓冲区?,cocoa,macos,core-graphics,Cocoa,Macos,Core Graphics,我正在寻找一种方法来抓取窗口的内容,比如CamTwist的“桌面+”功能。这可以抓住任何窗口,即使它在背景中 苹果的OpenGLScreenCapture示例展示了如何从主屏幕而不是隐藏表面进行捕获 知道CamTwist是如何访问NSWindow的像素缓冲区的吗?AFAIK您不能使用官方API访问。当然这是可能的,否则苹果将如何实施Exposé呢?人们通过逆向工程苹果的代码创造的;使用它的风险由您自己承担(作为一个私有API,这些调用中的任何一个都可能会随着苹果的任何发布而随时发生变化,并且不会

我正在寻找一种方法来抓取窗口的内容,比如CamTwist的“桌面+”功能。这可以抓住任何窗口,即使它在背景中

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


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

AFAIK您不能使用官方API访问。当然这是可能的,否则苹果将如何实施Exposé呢?人们通过逆向工程苹果的代码创造的;使用它的风险由您自己承担(作为一个私有API,这些调用中的任何一个都可能会随着苹果的任何发布而随时发生变化,并且不会发出任何通知),如果您正在使用它,不要指望苹果会让您进入他们的应用商店:-)正如您所看到的,您可以使用此API获取所有窗口(包括隐藏窗口)的列表你甚至可以操纵它们;虽然你真正被允许做什么可能取决于你的应用程序权限。这显示了如何使用这个私有API来捕获您喜欢的任何窗口的内容。请注意,代码的工作方式因操作系统版本而异,在10.5版本之前和10.5版本之后都有实现的方法,因此,如果您针对的是较旧的系统,请确保您也实现了这两种方法。用于真正获取映像的最终API调用不是私有的,顺便说一句,它们可以在官方SDK头中找到,只有获取不属于当前进程的窗口引用的方式是私有的


更新:从10.5开始,苹果公司公开了从Windows服务器复制WindowID的重要功能;因此,它不再是私有API。然而,在10.5之前已经可以检索这些WindowID了,但是标题当时还没有公开,而且在反向工程标题中找到的所有功能还没有公开。

AFAIK,官方API可以在CGWindow.h中找到,作为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.
中断


很抱歉,在苹果网站上找不到该文档的链接。但是,它们似乎有示例代码。

太棒了!抓取样本的儿子正是我想要的。你配得上你的绰号:-)
   /* 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);