Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Converting colors to unique constrast values.

Discussion in 'Scripting' started by Guy_Yome, Jun 5, 2015.

  1. Guy_Yome

    Guy_Yome

    Joined:
    Sep 30, 2014
    Posts:
    13
    I didn't really know how to write the title, but here it is.

    I want to write or to get an algorithm that takes a rgb or hex color and converts it into an unique int. For example, I want to compare two colors. If the difference between those colors is smaller than 100 ( or any value that fits the system ), we need to change one of the colors. Is there any way to do that or any premade way?
     
  2. Korno

    Korno

    Joined:
    Oct 26, 2014
    Posts:
    518
    Instead of doing that, why dont you just write a method that can compare the three color components. Give the difference as a percentage and then add those percentages together and check if the percentage difference is below a threshold?
     
  3. Guy_Yome

    Guy_Yome

    Joined:
    Sep 30, 2014
    Posts:
    13
    I think this way won't give the results I want. I need something more like a font contrast analyser. Example : http://webaim.org/resources/contrastchecker/
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    hex is a number, just in base 16
     
  5. Korno

    Korno

    Joined:
    Oct 26, 2014
    Posts:
    518
    Thinking about this a bit more - a color in the form of RGB is actually just a vector3 - couldnt you just calculate the length of the vectors and get the absolute difference between the lengths of each color (0 would be the same color, 0.1 very close etc, 25 would be quite far)
     
  6. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    RGB color isn't a vector3...

    The Color type in unity is stored as 3 float struct with values from 0->1 for each. You could techinically convert that to a Vector3.

    24-bit RGB color though is usually represented as a 3 byte couplet, with each couplet being an additive value for the 3 channels red green and blue. Each having a value from 0 to 255 (none to all).

    Note - you may see it usually called 32-bit colour, not 24. That's just the inclusion of the extra 8-bit alpha channel. Which contains no colour information at all... and is only useful when layering colour information.

    Here's the thing, if you represent this as your Vector3 idea, the magnitude is not really a good representation of the colour. The RGB colour space is not consistent through out, it favours some colours over others:



    Note how yellow is very under represented in the colour space.

    The differencing between colours is thusly not linear.

    Give you an example... if we took the 'length' of a vector3 that is full red, no green or blue:

    <1,0,0> or 0xFF0000

    Well the length would be... 1

    Full Blue though is:

    <0,0,1> or 0x0000FF

    The length is... 1.

    You just equated red and blue to one another.




    Even if we went with the OP's original idea. Lets take the values of:

    0xFF0000
    0xFE0000

    This is just 1 unity difference in red. Both would look almost identically red to the naked eye. Yet if you subtract the integer values of each:

    0xFF0000 - 0xFE0000 = 0x10000
    16711680 - 16646144 = 65536

    You just registered a 16^4 difference between the 2!




    Note, RGB isn't a full or real colour space. It fails to represent all the colours. The only reason we use it is because it allows us to compact colour information down to those colours humans would actually care to see.... or rather CAN see.

    See we don't actually see via mixing light of the primary colours. Instead we do so via 3 types of cones/rods in our eyes that measure redness, greeness and blueness... hence RGB. We accept that this storage mechanism doesn't really store a lot of yellow because we actually can't see yellow that well anyways!

    It's just like how in CD audio is only sampled at up to 44.1khz, the average human doesn't hear over 20,000hz, and you need to store twice that to maintain the fidelty of a frequency range... basically, a dog whistle can't be recorded to cd.



    So, other colour spaces, like HSL or HSV actually store more colours. BUT to maintain the fidelity of those colours us humans can actually see within it would require a large channel depth for each value that is greater than 8-bits. Meaning you'd need more memory to result in the same quality in the resulting image... despite actually containing more colour information... it's just colour information we don't see. Where as RGB can in a 8-bit depth per channel.
     
    Last edited: Jun 5, 2015
    Guy_Yome and blizzy like this.
  7. ThomasCreate

    ThomasCreate

    Joined:
    Feb 23, 2015
    Posts:
    81
    "The difference between the colours" is kind of an arbitrary way of looking at it. What difference are we talking about? The actual colour value (i.e. red vs blue), or also its saturation, maybe its brightness?

    However you end up defining it, it seems like a good call to convert the RGB color to HSV - that'll give you a better breakdown that makes more sense for comparing colours against each other.
     
  8. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Usually when you compare colours, you compare certain aspects of the colour.

    There's all sorts of things you can compare about the colour:

    the value of a certain colour cross section (compare the redness, or the yellownes... here you'd project the colour onto that range. Red's easy, it's the red of rgb, yellowness is harder since rgb is not perpendicular to yellow)

    That ones not common though... common comparisons are:

    compare brightness (luma)
    compare hue
    compare saturation

    Or compare multi-dimensionally through some of those. Like compare the brightness AND hue.
    Or comparing the chroma in and of itself is multidimensional (chroma being the differencing information for colour from a luma value... this is the YUV colour space)

    Here I have a few algorithms for converting RGB (in the form of the unity Color type) to hue, saturation, and luma:
    https://github.com/lordofduct/space...blob/master/SpacepuppyBase/Utils/ColorUtil.cs
     
    Guy_Yome and Korno like this.
  9. Korno

    Korno

    Joined:
    Oct 26, 2014
    Posts:
    518
    Lordofduct thanks for that information, I have to admit ignorance when it comes to color theory - the vector3 idea was just a spur of the moment idea. Thanks though, Very enlightening.
     
  10. Guy_Yome

    Guy_Yome

    Joined:
    Sep 30, 2014
    Posts:
    13
    Ok! Looking on all your answers I found an interesting site that show an example. http://snook.ca/technical/colour_contrast/colour.html#fg=333333,bg=333333
    I think I'll make a hue ratio and a brightness ratio average. If it goes under a certain point, I won't allow the color. It may not be perfect. But I think it will do the job right. I'll make an algorithm that changes the colors randomly according to those values and check if, with the treshold I put, it looks different enough.
     
    Last edited: Jun 5, 2015