В какой-то степени вы можете сделать это с помощью фильтров Core Image. Однако это частный API, поэтому вам нужно быть осторожным, потому что эти вещи могут измениться или исчезнуть в будущих выпусках OS X, и вы, очевидно, не сможете отправить приложение в App Store. Я не думаю, что это возможно с помощью публичных API.
Edit: ответ Николаю RUHE для лучшего метода, который использует публичный API. Вы можете сделать некоторые вещи с фильтрами Core Image, которые вы не могли бы сделать с гамма-таблицей (например, с использованием фильтров размытия и т. П.), Поэтому я оставлю свой ответ здесь.
Вот пример того, как инвертировать то, что за окном:
//Declarations to avoid compiler warnings (because of private APIs):
typedef void * CGSConnection;
typedef void * CGSWindowID;
extern OSStatus CGSNewConnection(const void **attributes, CGSConnection * id);
typedef void *CGSWindowFilterRef;
extern CGError CGSNewCIFilterByName(CGSConnection cid, CFStringRef filterName, CGSWindowFilterRef *outFilter);
extern CGError CGSAddWindowFilter(CGSConnection cid, CGSWindowID wid, CGSWindowFilterRef filter, int flags);
extern CGError CGSSetCIFilterValuesFromDictionary(CGSConnection cid, CGSWindowFilterRef filter, CFDictionaryRef filterValues);
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self.window setOpaque:NO];
[self.window setAlphaValue:1.0];
[self.window setBackgroundColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.1]];
self.window.level = NSDockWindowLevel;
CGSConnection thisConnection;
CGSWindowFilterRef compositingFilter;
int compositingType = 1; // under the window
CGSNewConnection(NULL, &thisConnection);
CGSNewCIFilterByName(thisConnection, CFSTR("CIColorInvert"), &compositingFilter);
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:3.0] forKey:@"inputRadius"];
CGSSetCIFilterValuesFromDictionary(thisConnection, compositingFilter, (CFDictionaryRef)options);
CGSAddWindowFilter(thisConnection, (CGSWindowID)[self.window windowNumber], compositingFilter, compositingType);
}
@end
(адаптировано из Steven Troughton Smith's article here)
Эффект не является совершенным, потому что по какой-то причине необходимо, чтобы в окне есть цвет фона, который не является полностью прозрачным, но он довольно близок.
Чтобы повлиять на весь экран, вы можете создать окно без полей, которое имеет ignoresMouseEvents
, установленное на YES
(так что вы можете щелкнуть по нему).
Вы можете поэкспериментировать с другими фильтрами, но не все из них могут работать для этого. Там какая-то информация о CGS...
функциях в этом обратном спроектированном заголовке: http://code.google.com/p/undocumented-goodness/source/browse/trunk/CoreGraphics/CGSPrivate.h
Очень интересно! Я не знал об этом. – omz