Существует ли традиционный метод инверсии значений NSColor?
Я ищу способ инвертировать произвольные значения NSColor во время выполнения, и, похоже, нет встроенного метода для этого.
Я буду использовать категорию для расширения NSColor
следующим образом:
NSColor * invertedColor = [someOtherColor inverted];
Вот прототип метода категории, который я использую:
@implementation NSColor (MyCategories)
- (NSColor *)inverted
{
NSColor * original = [self colorUsingColorSpaceName:
NSCalibratedRGBColorSpace];
return ...?
}
@end
Кто-нибудь может заполнить пробелы? Это не должно быть идеально, но я бы хотел, чтобы это имело смысл. то есть:
-
[[[NSColor someColor] inverted] inverted]
приведет к цвету, очень близкому к исходному цвету
-
[[NSColor whiteColor] inverted]
будет очень близко к [NSColor blackColor]
-
Инвертированные цвета будут на противоположных сторонах цветового круга. (красный и зеленый, желтый и фиолетовый и т.д.)
Альфа-значение должно оставаться таким же, как исходный NSColor
. Я только хочу инвертировать цвет, а не прозрачность.
ОБНОВЛЕНИЕ 3: (теперь в цвете!)
Оказывается, что использование дополнительного цвета (цвет с оттенком на 180 ° от исходного оттенка) недостаточно, поскольку белый и черный на самом деле не имеют значения оттенка. Исходя из ответа, предоставленного Феб, вот что я придумал:
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]()
Теперь подход Питера Хоси намного проще и дает лучшие результаты:
return [NSColor colorWithCalibratedRed:(1.0 - [original redComponent])
green:(1.0 - [original greenComponent])
blue:(1.0 - [original blueComponent])
alpha:[original alphaComponent]];
![color swatch #2]()
в Swift 4.2:
extension NSColor {
func inverted() -> NSColor? {
return NSColor(calibratedRed: 1.0 - redComponent,
green: 1.0 - greenComponent,
blue: 1.0 - blueComponent,
alpha: alphaComponent)
}
}
Ответы
Ответ 1
Простой: компоненты все 0-1, поэтому вычитайте каждый компонент из 1, чтобы получить значение дополнения.
Примеры:
- Красный = 1, 0, 0; дополнение = 0, 1, 1 = cyan
- Желтый = 1, 1, 0; дополнение = 0, 0, 1 = синий
- Белый = 1, 1, 1; дополнение = 0, 0, 0 = черный
- Глубокий оранжевый = 1, 0,25, 0; дополнение = 0, 0,75, 1 = голубой.
Как вы можете догадаться, это симметричная операция. Инвертирование инверсного значения даст вам именно тот цвет, с которого вы начали.
Ответ 2
Из того, что вы описываете, это похоже на то, что вы действительно хотите, - это функция, чтобы найти цветное дополнение, а не его обратное. Инвертирование означает что-то другое в этом контексте.
fooobar.com/questions/120609/.... Возможно, какой-то код можно адаптировать?
Здесь представлена некоторая интересная и потенциально полезная информация о различных способах обработки цвета в цветовых пространствах Cocoa. Из того, что здесь выглядит, если вы можете использовать цветовое пространство HSV, то дополнение цвета можно найти, просто взяв hue > 179 ? hue -= 180 : hue = += 180
, так как оттенки определяются вокруг цветового круга в полном круге.
Ответ 3
Вот некоторые oneliner с пользовательским установщиком (альфа не отменена!):
-(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)];
}