Comparing colors and identifying the closest match within an array is a common task in graphics applications. In this article, we'll explore three different methods to accomplish this:
1. Hue-Only Comparison:
This method considers only the hues of the colors, ignoring saturation and brightness. The hue distance is calculated using a simple subtraction, and the closest hue is determined by finding the minimum distance.
2. RGB Distance:
This method measures the direct distance between the RGB values of the colors. The color difference is calculated as a Euclidean distance in the RGB space, and the closest color is found by minimizing this difference.
3. Weighted Hue, Saturation, and Brightness Comparison:
This method combines hue, saturation, and brightness in a weighted manner. The perceived brightness is calculated, and a color number is computed based on saturation and brightness. The closest color is determined by minimizing the weighted sum of the color difference and the hue distance.
Here are the implementations of these methods:
// Hue-Only Comparison int closestColor1(List<Color> colors, Color target) { var hue1 = target.GetHue(); var diffs = colors.Select(n => getHueDistance(n.GetHue(), hue1)); var diffMin = diffs.Min(n => n); return diffs.ToList().FindIndex(n => n == diffMin); } // RGB Distance Comparison int closestColor2(List<Color> colors, Color target) { var colorDiffs = colors.Select(n => ColorDiff(n, target)).Min(n => n); return colors.FindIndex(n => ColorDiff(n, target) == colorDiffs); } // Weighted Hue, Saturation, and Brightness Comparison int closestColor3(List<Color> colors, Color target) { float hue1 = target.GetHue(); var num1 = ColorNum(target); var diffs = colors.Select(n => Math.Abs(ColorNum(n) - num1) + getHueDistance(n.GetHue(), hue1)); var diffMin = diffs.Min(x => x); return diffs.ToList().FindIndex(n => n == diffMin); }
// Color brightness as perceived: float getBrightness(Color c) => (c.R * 0.299f + c.G * 0.587f + c.B * 0.114f) / 256f; // Distance between two hues: float getHueDistance(float hue1, float hue2) => Math.Abs(hue1 - hue2) > 180 ? 360 - Math.Abs(hue1 - hue2) : Math.Abs(hue1 - hue2); // Weighed by saturation and brightness: float ColorNum(Color c) => c.GetSaturation() * factorSat + getBrightness(c) * factorBri; // Distance in RGB space: int ColorDiff(Color c1, Color c2) => (int)Math.Sqrt((c1.R - c2.R) * (c1.R - c2.R) + (c1.G - c2.G) * (c1.G - c2.G) + (c1.B - c2.B) * (c1.B - c2.B));
The choice of color distance metric depends on the specific application. If hue is the primary consideration, the hue-only comparison is sufficient. For more general color matching, the RGB distance or weighted hue, saturation, and brightness comparison methods provide more accurate results.
The above is the detailed content of How to Find the Closest Color in a Color Array?. For more information, please follow other related articles on the PHP Chinese website!