Comparing NSColor instances

  • I have the need to compare multiple NSColor instances to see if they
    all represent the same color.  This is so I can correctly support
    multiple selection in a new IB 3.0 plugin.

    My first approach was to "normalize" all colors like so:

    NSColor* normalizedColor = [aColor colorUsingColorSpace:[NSColorSpace
    genericRGBColorSpace]];

    Then, extract the RGB components with getRed:green:blue:alpha: so I
    could do a simple comparison of them.

    But, when calling getRed::::, I get the following in the Console:

    *** -getRed:green:blue:alpha: not defined for the NSColor
    NSCustomColorSpace Generic RGB colorspace 0 0 0 1; need to first
    convert colorspace.

    Also tried deviceRGBColorSpace, but got the same results.

    I know this is possible as Apple has a solution.  If you inspect two
    or more instances of an object in IB such that one the object's
    attributes links to an NSColorWell, the color well reverts to a
    default (black) should the object instances have different color values.

    Searching for this issue just brought up the fact that the "problem is
    tricky to solve" and that one should look at color spaces.  I would
    have thought normalizing to a common color space would have done the
    trick.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On Nov 4, 2007, at 8:29 PM, Ricky Sharp wrote:

    > I have the need to compare multiple NSColor instances to see if they
    > all represent the same color.  This is so I can correctly support
    > multiple selection in a new IB 3.0 plugin.
    >
    > My first approach was to "normalize" all colors like so:
    >
    > NSColor* normalizedColor = [aColor colorUsingColorSpace:
    > [NSColorSpace genericRGBColorSpace]];
    >
    > Then, extract the RGB components with getRed:green:blue:alpha: so I
    > could do a simple comparison of them.
    >
    > But, when calling getRed::::, I get the following in the Console:
    >
    > *** -getRed:green:blue:alpha: not defined for the NSColor
    > NSCustomColorSpace Generic RGB colorspace 0 0 0 1; need to first
    > convert colorspace.
    >
    > Also tried deviceRGBColorSpace, but got the same results.

    My assumption above was that since I was using an 'RGB' color space,
    that one could then call getRed:green:blue:alpha:.

    I do have a working solution to where I still normalize to the same
    color space, but then use numberOfComponents followed by a
    getComponents: with a CGFloat array.  I then compare the values in the
    array.

    I should beef up the code though to handle the case where calling
    numberOfComponents can raise an exception (if no floating point
    components exist for the color).

    Also, I'm never keen on doing exact compares on floating point values,
    so I may add in a bit of "slop" to the compare.  On the other hand, if
    I do normalize two colors to the same color space, it should be
    reasonable to assume it will have identical valued components.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On Nov 4, 2007, at 6:58 PM, Ricky Sharp wrote:

    > Also, I'm never keen on doing exact compares on floating point
    > values, so I may add in a bit of "slop" to the compare.  On the
    > other hand, if I do normalize two colors to the same color space,
    > it should be reasonable to assume it will have identical valued
    > components.

    Use the slop. I can easily envision a scenario where converting RGB-
    > CMYK-> RGB could introduce error. Just because the algebra cleanly
    reduces out to nothing doesn't mean the CPU will introduce zero error
    along the way.
  • On Nov 4, 2007, at 6:58 PM, Ricky Sharp wrote:

    > On Nov 4, 2007, at 8:29 PM, Ricky Sharp wrote:
    >
    >> I have the need to compare multiple NSColor instances to see if
    >> they all represent the same color.  This is so I can correctly
    >> support multiple selection in a new IB 3.0 plugin.
    >>
    >> My first approach was to "normalize" all colors like so:
    >>
    >> NSColor* normalizedColor = [aColor colorUsingColorSpace:
    >> [NSColorSpace genericRGBColorSpace]];
    >>
    >> Then, extract the RGB components with getRed:green:blue:alpha: so I
    >> could do a simple comparison of them.
    >>
    >> But, when calling getRed::::, I get the following in the Console:
    >>
    >> *** -getRed:green:blue:alpha: not defined for the NSColor
    >> NSCustomColorSpace Generic RGB colorspace 0 0 0 1; need to first
    >> convert colorspace.
    >>
    >> Also tried deviceRGBColorSpace, but got the same results.
    >
    > My assumption above was that since I was using an 'RGB' color space,
    > that one could then call getRed:green:blue:alpha:.
    >
    > I do have a working solution to where I still normalize to the same
    > color space, but then use numberOfComponents followed by a
    > getComponents: with a CGFloat array.  I then compare the values in
    > the array.
    >
    > I should beef up the code though to handle the case where calling
    > numberOfComponents can raise an exception (if no floating point
    > components exist for the color).
    >
    > Also, I'm never keen on doing exact compares on floating point
    > values, so I may add in a bit of "slop" to the compare.  On the
    > other hand, if I do normalize two colors to the same color space, it
    > should be reasonable to assume it will have identical valued
    > components.

    If accuracy is important (might not be depending on your application),
    you should convert to a larger color space for your comparisons, maybe
    Lab or Xyz. I don't think Generic RGB is terribly large.

    Also, someone on the Quartz or ColorSync lists might be able to
    suggest a good solution to your problem.

    Dave
  • The getRed:... type methods work only in colors in the named color
    spaces, such as NSCalibratedRGBColorSpace.

    Colors in "custom" color spaces such as [NSColorSpace
    genericRGBColorSpace] respond to the getComponents: and
    numberOfComponents accessors. These actually work for all color space
    types which floating point components.

    Ali

    On Nov 4, 2007, at 18:58 , Ricky Sharp wrote:

    >
    > On Nov 4, 2007, at 8:29 PM, Ricky Sharp wrote:
    >
    >> I have the need to compare multiple NSColor instances to see if
    >> they all represent the same color.  This is so I can correctly
    >> support multiple selection in a new IB 3.0 plugin.
    >>
    >> My first approach was to "normalize" all colors like so:
    >>
    >> NSColor* normalizedColor = [aColor colorUsingColorSpace:
    >> [NSColorSpace genericRGBColorSpace]];
    >>
    >> Then, extract the RGB components with getRed:green:blue:alpha: so I
    >> could do a simple comparison of them.
    >>
    >> But, when calling getRed::::, I get the following in the Console:
    >>
    >> *** -getRed:green:blue:alpha: not defined for the NSColor
    >> NSCustomColorSpace Generic RGB colorspace 0 0 0 1; need to first
    >> convert colorspace.
    >>
    >> Also tried deviceRGBColorSpace, but got the same results.
    >
    >
    > My assumption above was that since I was using an 'RGB' color space,
    > that one could then call getRed:green:blue:alpha:.
    >
    > I do have a working solution to where I still normalize to the same
    > color space, but then use numberOfComponents followed by a
    > getComponents: with a CGFloat array.  I then compare the values in
    > the array.
    >
    > I should beef up the code though to handle the case where calling
    > numberOfComponents can raise an exception (if no floating point
    > components exist for the color).
    >
    > Also, I'm never keen on doing exact compares on floating point
    > values, so I may add in a bit of "slop" to the compare.  On the
    > other hand, if I do normalize two colors to the same color space, it
    > should be reasonable to assume it will have identical valued
    > components.
    >
    > ___________________________________________________________
    > Ricky A. Sharp        mailto:<rsharp...>
    > Instant Interactive(tm)  http://www.instantinteractive.com
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today