2010-01-27 2 views
18

Я ищу способ инвертировать произвольные значения 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. (Красный & зеленый, желтый & фиолетовый, и т.д.)

Значение альфа должны оставаться такими же, как оригинал NSColor. Я только ищу инвертировать цвет, а не прозрачность.

UPDATE 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

ответ

21

Простой: компоненты все 0-1, поэтому вычитайте каждый компонент из 1, чтобы получить значение дополнения.

Примеры:

  • Красный = 1, 0, 0; дополнение = 0, 1, 1 = циан
  • Желтый = 1, 1, 0; дополнение = 0, 0, 1 = синий
  • Белый = 1, 1, 1; дополнение = 0, 0, 0 = черный
  • Deep orange = 1, 0.25, 0; дополнение = 0, 0,75, 1 = голубой

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

+0

Упрощенный за то, что он прост в этом :) – phoebus

+0

Примечание: для серого = 0,5, 0,5, 0,5; дополнение - это само по себе. – Pang

3

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

Here's a StackOverflow question regarding complements in JavaScript. Возможно, какой-то код можно адаптировать?

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

+0

Это Java-код выглядит многообещающим. Я дам ему вихрь. –

+0

И спасибо вам за то, что они дополняют цвета и инвертированные цвета. Я добавлю это к вопросу. –

1

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

вы можете рассмотреть возможность использования const CGFloat * cc = CGColorGetComponents (originalColor.CGColor); return [UIColor colorWithRed: (1-cc [0]) зеленый: (1-cc [1]) синий: (1-cc [2]) alpha: CGColorGetAlpha (originalColor.CGColor)]; (зачем вызывать функцию 3 раза, чтобы получить тот же результат?) – unsynchronized

Смежные вопросы