屏幕颜色反转如何在OS X中工作?

Ale*_*kov 4 cocoa objective-c colortransform

这就是OS X内置的颜色反转功能可以将您的屏幕转换为:

在此输入图像描述

它可以反转所有颜色,将它们变为灰度,调整对比度.现在我想构建自己的实现,因此需要专业人士的建议.

无法捕获倒置屏幕让我觉得反转是一种调整层,它位于所有窗口之上,并且不会暴露于交互事件.是这样吗?它是通过OpenGL库完成的吗?

我不是关注实际的编码帮助,而是研究解决问题的设计/方法.在我的目标应用程序中,我需要定义输出颜色diapasons并应用颜色转换规则(input => output).

提前致谢.

Nik*_*uhe 12

Mac OS进行颜色反转的方式(可能)是通过使用Quartz Display Services来修改显卡的伽玛表.

图形卡有两个这样的表,用于在合成后修改颜色输出到最终帧缓冲区.其中一个可以被应用程序修改,以改变屏幕显示任何RGB值的方式.

这是反转显示的代码:

//ApplicationServices includes CoreGraphics
#import <ApplicationServices/ApplicationServices.h>

int main(int argc, const char * argv[])
{
    CGGammaValue table[] = {1, 0};
    CGSetDisplayTransferByTable(CGMainDisplayID(), sizeof(table) / sizeof(table[0]), table, table, table);
    sleep(3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)


omz*_*omz 5

在某种程度上,您可以使用 Core Image 过滤器来做到这一点。然而,这是私有 API,所以你需要小心,因为这些东西可能会在未来的 OS X 版本中改变或消失,而且你显然不能将你的应用程序提交到 App Store。我认为公共 API 不可能实现这样的事情。

编辑:有关使用公共 API 的更好方法,请参阅 Nikolai Ruhe 的回答。你可以用 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
Run Code Online (Sandbox Code Playgroud)

(改编自史蒂文·特劳顿·史密斯Steven Troughton Smith)的文章在这里

截屏

效果并不完美,因为出于某种原因,窗口必须具有不完全透明的背景颜色,但它非常接近。

要影响整个屏幕,您可以创建一个ignoresMouseEvents设置为YES(以便您可以单击它)的无边框窗口。

您可以尝试使用其他过滤器,但并非所有过滤器都适用于此。有一些关于CGS...这个反向工程标题中的功能的信息:http : //code.google.com/p/undocumented-goodness/source/browse/trunk/CoreGraphics/CGSPrivate.h