Существует ли обычный метод инвертирования значений 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°, но я также инвертирую компонент яркости, чтобы очень темные цвета стали очень яркими (и наоборот).Это позаботится о черно-белых случаях, но инвертирует почти каждый цвет в черный (что нарушает мое правило двойной инверсии).Вот результаты:
Сейчас, Подход Питера Хоузи намного проще и дает лучшие результаты:
return [NSColor colorWithCalibratedRed:(1.0 - [original redComponent])
green:(1.0 - [original greenComponent])
blue:(1.0 - [original blueComponent])
alpha:[original alphaComponent]];
в Свифте 4.2:
extension NSColor {
func inverted() -> NSColor? {
return NSColor(calibratedRed: 1.0 - redComponent,
green: 1.0 - greenComponent,
blue: 1.0 - blueComponent,
alpha: alphaComponent)
}
}
Решение
Простой:Все компоненты имеют значения от 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 = небесно-голубой
Как вы можете догадаться, это симметричная операция.Инвертирование обратного даст вам точно цвет, с которого вы начали.
Другие советы
Судя по тому, что вы описываете, похоже, что вам действительно нужна функция для поиска дополнения к цвету, а не его инверсии.Инвертирование в данном контексте означает нечто иное.
Вот вопрос StackOverflow относительно дополнений в JavaScript.Возможно, часть кода можно адаптировать?
Здесь это интересная и потенциально полезная информация о различных способах работы с цветом в цветовых пространствах Cocoa.Судя по тому, как это выглядит здесь, если вы можете использовать цветовое пространство HSV, то дополнение цвета можно найти, просто взяв hue > 179 ? hue -= 180 : hue = += 180
, поскольку оттенки определяются вокруг цветового круга по полному кругу.
Вот какой-то однострочник с пользовательским установщиком (альфа-версия не перевернута!):
-(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)];
}