Is there an easy way to compare how close two colors are to each other?

Solution 1:

You probably want to convert the colors to an HSL model (Hue, Saturation, Lightness) and then compare the values within thresholds in the order HSL. If the hue is within a tolerance deemed as "close", then check the "closeness" of the saturation, and then the lightness.

Solution 2:

Delta-e, is a single number that represents the perceived 'distance' between two colors. The lower the number, the more similar the colors are to the human eye.

There are a few different ways to calculate it...CIE76 (aka CIE 1976 or dE76) being the most popular.

  • CIE76
  • CMC l:c
  • dE94
  • dE2000

Each one goes about things in a different way, but for the most part they all require you to convert to a better (for comparison) color model than RGB.

For CIE76 you basically just convert your colors to the LAB color space, then compute the 3 dimensional distance between them.

Wikipedia has all the formulae: http://en.wikipedia.org/wiki/Color_difference

You can check your work with online color calculators:

  • CIE76
  • CMC l:c

Solution 3:

I'm not sure of any algorithms, you may want to consider converting RGB (Red, Green, Blue) values in to HSB (Hue, Saturation, Brightness).

Hue is essentially "color", so you can compare simply on how close the Hue values are.

See http://en.wikipedia.org/wiki/HSV_color_space

Solution 4:

I know this question is 10 years old but extending Joe Zack's answer:

Here is my Kotlin code

//Entry point here
//Color must be hexa for example "#829381"
fun calculateColorDistance(colorA: String, colorB: String): Double {
    val aColorRGBArray = getColorRGBArray(colorA)
    val bColorRGBArray = getColorRGBArray(colorB)
    val aColorLAB = getColorLab(aColorRGBArray)
    val bColorLAB = getColorLab(bColorRGBArray)
    return calculateColorDistance(aColorLAB, bColorLAB)
}

private fun calculateColorDistance(aColorLAB: DoubleArray, bColorLAB: DoubleArray): Double {
    val lab = aColorLAB[0] - bColorLAB[0]
    val aab = aColorLAB[1] - bColorLAB[1]
    val bab = aColorLAB[2] - bColorLAB[2]
    val sqrtlab = lab.pow(2)
    val sqrtaab = aab.pow(2)
    val sqrtbab = bab.pow(2)

    val sum = sqrtlab + sqrtaab + sqrtbab
    return sqrt(sum)
}

private fun getColorRGBArray(color: String): IntArray {
    val cleanColor = color.replace("#", "")
    val colorInt = Integer.parseInt(cleanColor, 16)
    val r = Color.red(colorInt)
    val g = Color.green(colorInt)
    val b = Color.blue(colorInt)
    return intArrayOf(r, g, b)
}

private fun getColorLab(colorRGB: IntArray): DoubleArray {
    val outLab = doubleArrayOf(0.0,0.0,0.0)
    ColorUtils.RGBToLAB(colorRGB[0], colorRGB[1], colorRGB[2], outLab)
    return outLab
}

calculateColorDistance will return a Double value. the lower this value is the more similar the colors are.

Hope this helps someone