是否有反转 NSColor 值的常规方法?

发布于 2024-08-19 11:14:53 字数 2975 浏览 4 评论 0 原文

我正在寻找一种方法来反转任意 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. 反转颜色将位于 色轮。 (红色和绿色,黄色和紫色等)

alpha 值应与原始 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

现在,Peter Hosey 的方法要简单得多,而且效果更好:

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

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.:

  1. [[[NSColor someColor] inverted] inverted] would result in a color very close to the original color

  2. [[NSColor whiteColor] inverted] would be very close to [NSColor blackColor]

  3. 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:

color swatch #1

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]];

color swatch #2

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

全部不再 2024-08-26 11:14:53

简单:分量都是 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 = 天蓝色

正如您所猜测的,这是一个对称操作。反转反转将使您完全获得您开始时使用的颜色。

Simple: The components are all 0–1, so subtract each component from 1 to get the complement's value.

Examples:

  • Red = 1, 0, 0; complement = 0, 1, 1 = cyan
  • Yellow = 1, 1, 0; complement = 0, 0, 1 = blue
  • White = 1, 1, 1; complement = 0, 0, 0 = black
  • Deep orange = 1, 0.25, 0; complement = 0, 0.75, 1 = sky blue

As you can guess, this is a symmetric operation. Inverting the inverse will get you exactly the color you started with.

凡间太子 2024-08-26 11:14:53

从你的描述来看,听起来你真正想要的是一个找到颜色补色的函数,而不是它的反色。在这种情况下,反转意味着不同的东西。

这是一个有关 JavaScript 补码的 StackOverflow 问题。也许某些代码是适应性强的?

这里是一些有趣且潜在的有关在 Cocoa 色彩空间中使用颜色的各种方式的有用信息。从这里看起来,如果您可以使用 HSV 颜色空间,那么只需采用 hue > 就可以找到颜色的补色。 179?色调 -= 180 : 色调 = += 180,因为色调是围绕色轮完整定义的。

From what you describe, it sounds like what you really want is a function to find a color's complement, not its inverse. Inverting means something different in this context.

Here's a StackOverflow question regarding complements in JavaScript. Perhaps some of the code is adaptable?

Here is some interesting and potentially useful info about the various ways color can be worked with in Cocoa color spaces. From what it looks like here, if you can use the HSV color space, then the complement of a color could be found by simply taking hue > 179 ? hue -= 180 : hue = += 180, since the hues are defined around the color wheel in a full circle.

北陌 2024-08-26 11:14:53

这是一些带有自定义设置器的 oneliner(alpha 没有反转!):

-(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)];
}

Here is some oneliner with custom setter (alpha is not reversed!):

-(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)];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文