是否存在反转NSColor值的常规方法?

时间:2010-01-27 06:27:40

标签: cocoa invert nscolor

我正在寻找一种在运行时反转任意NSColor值的方法,并且似乎没有任何内置方法可以这样做。

我将使用类别扩展NSColor,如下所示:

NSColor * invertedColor = [someOtherColor inverted];

以下是我正在使用的类别方法原型:

@implementation NSColor (MyCategories)
- (NSColor *)inverted
{
    NSColor * original = [self colorUsingColorSpaceName:
                      NSCalibratedRGBColorSpace];
    return ...?
}
@end

任何人都可以填空吗?这不一定是完美的,但我希望它有所帮助。即:

  1. [[[NSColor someColor] inverted] inverted]会产生非常接近原始颜色的颜色

  2. [[NSColor whiteColor] inverted]非常接近[NSColor blackColor]

  3. 倒置的颜色位于color wheel的两侧。 (红色和绿色,黄色和紫色等)

  4. Alpha值应与原始NSColor保持一致。我只是想要反转颜色,而不是透明度。

    更新3: (现在有颜色!)

    事实证明,使用complementary color(一种距离原始色调180度的色调)还不够,因为白色和黑色实际上没有色调值。从phoebus提供的答案开始,这就是我想出的:

    CGFloat hue = [original hueComponent];
    if (hue >= 0.5) { hue -= 0.5; } else { hue += 0.5; }
    return [NSColor colorWithCalibratedHue:hue
                                saturation:[original saturationComponent]
                                brightness:(1.0 - [original brightnessComponent])
                                     alpha:[original alphaComponent]];
    

    色调仍然旋转了180°,但我也将亮度成分反转,使非常暗的颜色变得非常明亮(反之亦然)。这样可以处理黑白情况,但它会将每种颜色反转为黑色(这违反了我的双反转规则)。结果如下:

    color swatch #1 http://img29.imageshack.us/img29/8548/invert1.jpg

    现在,Peter Hosey's approach更加简单,它可以产生更好的结果:

    return [NSColor colorWithCalibratedRed:(1.0 - [original redComponent])
                                     green:(1.0 - [original greenComponent])
                                      blue:(1.0 - [original blueComponent])
                                     alpha:[original alphaComponent]];
    

    color swatch #2 http://img29.imageshack.us/img29/1513/invert2.jpg

    Swift 4.2中的

    extension NSColor {
    
        func inverted() -> NSColor? {
            return NSColor(calibratedRed: 1.0 - redComponent,
                                   green: 1.0 - greenComponent,
                                   blue: 1.0 - blueComponent,
                                   alpha: alphaComponent)
        }
    } 
    

3 个答案:

答案 0 :(得分:22)

简单:组件都是0-1,因此从1中减去每个组件以获得补码的值。

示例:

  • 红色= 1,0,0;补码= 0,1,1 =青色
  • 黄色= 1,1,0;补码= 0,0,1 =蓝色
  • 白= 1,1,1;补码= 0,0,0 =黑色
  • 深橙色= 1,0.25,0;补数= 0,0.75,1 =天蓝色

你可以猜到,这是一个对称的操作。反转反转将使您完全您开始使用的颜色。

答案 1 :(得分:3)

根据你所描述的,听起来你真正想要的是找到颜色补码的功能,而不是它的反转。倒置意味着在这种情况下不同的东西。

Here's a StackOverflow question regarding complements in JavaScript。也许有些代码可以适应?

Here是一些有趣且可能有用的信息,介绍了在Cocoa颜色空间中可以使用颜色的各种方法。从这里的样子来看,如果你可以使用HSV色彩空间,那么只需取hue > 179 ? hue -= 180 : hue = += 180即可找到颜色的补码,因为色调是围绕色轮定义的一整圈。

答案 2 :(得分:1)

以下是一些带有自定义设置器的oneliner(alpha未反转!):

-(void)setReverseFontColor:(UIColor *)reverseFontColor {
     _reverseFontColor = [AppSingleStyle reversedColorFromOriginal:reverseFontColor];
}

+(UIColor*)reversedColorFromOriginal:(UIColor*)originalColor {
    return [UIColor colorWithRed:(1-CGColorGetComponents(originalColor.CGColor)[0]) green:(1-CGColorGetComponents(originalColor.CGColor)[1]) blue:(1-CGColorGetComponents(originalColor.CGColor)[2]) alpha:CGColorGetAlpha(originalColor.CGColor)];
}