Есть ли обычный метод для инвертирования значений NSColor? - PullRequest
19 голосов
/ 27 января 2010

Я ищу способ инвертировать произвольные NSColor значения во время выполнения, и, похоже, нет встроенного метода для этого.

Я буду использовать категорию для расширения NSColor следующим образом:

NSColor * invertedColor = [someOtherColor inverted];

Вот прототип метода категории, который я использую:

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

Может кто-нибудь заполнить пробелы? Это не должно быть идеально, но я бы хотел, чтобы это имело смысл. i.e.:

  1. [[[NSColor someColor] inverted] inverted] приведет к цвету, очень близкому к исходному цвету

  2. [[NSColor whiteColor] inverted] будет очень близко к [NSColor blackColor]

  3. Инвертированные цвета будут на противоположных сторонах цветового круга . (красный и зеленый, желтый и фиолетовый и т. д.)

Альфа-значение должно оставаться таким же, как и исходное NSColor. Я только хочу инвертировать цвет , а не прозрачность.

ОБНОВЛЕНИЕ 3: (теперь в цвете!)

Оказывается, что использование дополнительного цвета (цвет с оттенком на 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

Теперь, Подход Питера Хоси намного проще, и он дает лучшие результаты:

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)
    }
} 

Ответы [ 3 ]

22 голосов
/ 27 января 2010

Простой: все компоненты имеют 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 = голубой

Как вы можете догадаться, это симметричная операция. Инвертирование инверсии даст вам точно цвет, с которого вы начали.

3 голосов
/ 27 января 2010

Из того, что вы описываете, звучит так, как будто вы действительно хотите найти функцию дополнения цвета, а не его инверсию. Инвертирование означает что-то другое в этом контексте.

Вот вопрос StackOverflow относительно дополнений в JavaScript . Возможно, часть кода адаптируется?

Здесь - некоторая интересная и потенциально полезная информация о различных способах работы с цветом в цветовых пространствах Какао. Исходя из того, как это выглядит здесь, если вы можете использовать цветовое пространство HSV, то дополнение цвета можно найти, просто взяв hue > 179 ? hue -= 180 : hue = += 180, поскольку оттенки определяются вокруг цветового круга в полном круге.

1 голос
/ 07 июля 2013

Вот некоторый 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)];
}
...