I'm looking for a way to invert arbitrary NSColor values at runtime, and there doesn't appear to be any built-in method to do so.
I will be using a category to extend NSColor
as follows:
NSColor * invertedColor = [someOtherColor inverted];
Here is the category method prototype that I am using:
@implementation NSColor (MyCategories)
- (NSColor *)inverted
{
NSColor * original = [self colorUsingColorSpaceName:
NSCalibratedRGBColorSpace];
return ...?
}
@end
Can anyone fill in the blanks? This doesn't have to be perfect, but I would like it to make some sense. i.e.:
[[[NSColor someColor] inverted] inverted]
would result in a color very close to the original color[[NSColor whiteColor] inverted]
would be very close to[NSColor blackColor]
Inverted colors would be on opposite sides of the color wheel. (red & green, yellow & violet, etc.)
The alpha value should remain the same as the original NSColor
. I'm only looking to invert the color, not the transparency.
UPDATE 3: (now in color!)
It turns out that using a complementary color (a color with a hue 180° away from the original hue) is not quite enough, since white and black don't really have a hue value. Starting from the answer provided by phoebus, this is what I came up with:
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]];
The hue is still rotated 180°, but I also invert the brightness component so that very dark colors become very bright (and vice versa). This takes care of the black and white cases, but it inverts just about every color to black (which violates my double-inversion rule). Here are the results:
Now, Peter Hosey's approach is much simpler, and it produces better results:
return [NSColor colorWithCalibratedRed:(1.0 - [original redComponent])
green:(1.0 - [original greenComponent])
blue:(1.0 - [original blueComponent])
alpha:[original alphaComponent]];
in Swift 4.2:
extension NSColor {
func inverted() -> NSColor? {
return NSColor(calibratedRed: 1.0 - redComponent,
green: 1.0 - greenComponent,
blue: 1.0 - blueComponent,
alpha: alphaComponent)
}
}