Как получить доступ к пиксельному буферу NSWindow в OSX? - PullRequest
6 голосов
/ 28 марта 2011

Я ищу способ получить содержимое окна, например CamTwist «Desktop +». Это может захватить любое окно, даже если оно находится в фоновом режиме.

Пример Apple OpenGLScreenCapture показывает, как снимать с основного экрана, но не со скрытых поверхностей.

Есть идеи, как CamTwist получает доступ к пиксельному буферу NSWindow?

Ответы [ 2 ]

5 голосов
/ 29 марта 2011

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.

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.Тем не менее, они, кажется, имеют пример кода в Сын Захвата .

4 голосов
/ 29 марта 2011

AFAIK, вы не можете сделать это с помощью официального API.Конечно, это возможно, иначе как бы Apple реализовала Exposé в противном случае? Здесь вы можете найти заголовок , который люди создали путем обратного инжиниринга кода Apple;используйте его на свой страх и риск (будучи частным API, любой из этих вызовов может измениться с любым выпуском от Apple в любое время и без какого-либо уведомления) и не ожидайте, что Apple впустит вас в свой App Store, если вы его используете:-) Как вы можете видеть, вы можете использовать этот API, чтобы получить список всех окон (включая скрытые) всех приложений, и вы даже можете манипулировать ими;хотя то, что вам действительно разрешено делать, может зависеть от привилегий вашего приложения. А вот код , который показывает, как вы можете использовать этот закрытый API для захвата содержимого любого окна, которое вам нравится.Обратите внимание, что код работает по-разному в зависимости от версии ОС, есть способ, как сделать это до 10.5 и как после 10.5, поэтому, если вы ориентируетесь на старые системы, убедитесь, что вы также реализуете оба способа.Заключительные вызовы API, используемые для реального получения изображения, не являются частными, кстати, они находятся в официальных заголовках SDK, только способ, которым вы получаете ссылку на окно, которое не принадлежит вашему текущему процессу, является закрытым.

Обновление : Начиная с 10.5, Apple опубликовала важную функцию для копирования идентификаторов WindowID с сервера окон;так что это уже не приватный API.Тем не менее, уже можно было получить эти WindowID до 10.5, но в то время заголовок не был общедоступным, и все же не все функции, обнаруженные в обращенном инженерном заголовке, были обнародованы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...