Question

I am looking to sort a list by "color distance." I am using the following function to calculate the distance between two colors:

double colorDistance(Color c1, Color c2) {
    double rmean = (c1.getRed() + c2.getRed()) / 2;
    int r = c1.getRed() - c2.getRed();
    int g = c1.getGreen() - c2.getGreen();
    int b = c1.getBlue() - c2.getBlue();
    double weightR = 2 + rmean / 256;
    double weightG = 4.0;
    double weightB = 2 + (255 - rmean) / 256;
    return Math.sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
}

So, as you can see, I am using the RGB values to calculate "distance" between two colors. This function works fantastically for what I need to calculate as I don't require exact precision. The problem is, I need to be able to tell, not only distance, but whether c1 comes before or after c2 so that I can create a sorted list based on color distance.

In case that isn't clear enough, an example might help. The color distance between pure black and pure white will be somewhere in the vicinity of 256. In its current state, this function will return the same ~256 for colorDistance(black, white) and colorDistance(white, black). How could I make it so that colorDistance(black, white) returns 256 and colorDistance(white, black) returns -256?

I'm not averse to using HSV/HSL if that is an option, but I am far more familiar with RGB. If a function could be provided for calculating positive or negative color distance with HSV/HSL then bring it on!

Or even better yet, another simple function that will take two colors and simply decide whether c1 comes before or after c2!

Was it helpful?

Solution

You can multiply the answer by negative 1 if:

int pixel = (red & 0xFF) << 24 |
              (blue & 0xFF) << 16 |
              (green & 0xFF) <<  8 |
              (255 & 0xFF); // 255 is alpha value

is less than the other color's pixel.

Edit: I left alpha value in case you want to use it in the future. If not, then you can take that part out and reduce every shift by 8. Like so:

int pixel = (red & 0xFF) << 16 |
            (blue & 0xFF) << 8 |
            (green & 0xFF);

OTHER TIPS

You can try make an array of RGB colors by representing them as hexadecimal numbers and then sort the list by value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top