using System.Runtime.CompilerServices; namespace GHelper.Helpers { public class ColorUtils { // Method to get the weighted average between two colors public static Color GetWeightedAverage(Color color1, Color color2, float weight) { int red = (int)Math.Round(color1.R * (1 - weight) + color2.R * weight); int green = (int)Math.Round(color1.G * (1 - weight) + color2.G * weight); int blue = (int)Math.Round(color1.B * (1 - weight) + color2.B * weight); red = Math.Min(255, Math.Max(0, red)); green = Math.Min(255, Math.Max(0, green)); blue = Math.Min(255, Math.Max(0, blue)); return Color.FromArgb(red, green, blue); } public static Color GetMidColor(Color color1, Color color2) { return Color.FromArgb((color1.R + color2.R) / 2, (color1.G + color2.G) / 2, (color1.B + color2.B) / 2); } public static Color GetDominantColor(Bitmap bmp) { //Used for tally int r = 0; int g = 0; int b = 0; int total = 0; for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) { Color clr = bmp.GetPixel(x, y); r += clr.R; g += clr.G; b += clr.B; total++; } } //Calculate average r /= total; g /= total; b /= total; return Color.FromArgb(r, g, b); } public class HSV { public double Hue { get; set; } public double Saturation { get; set; } public double Value { get; set; } public Color ToRGB() { var hue = Hue * 6; var saturation = Saturation; var value = Value; double red; double green; double blue; if (saturation == 0) { red = green = blue = value; } else { var i = Convert.ToInt32(Math.Floor(hue)); var f = hue - i; var p = value * (1 - saturation); var q = value * (1 - saturation * f); var t = value * (1 - saturation * (1 - f)); int mod = i % 6; red = new[] { value, q, p, p, t, value }[mod]; green = new[] { t, value, value, q, p, p }[mod]; blue = new[] { p, p, t, value, value, q }[mod]; } return Color.FromArgb(Convert.ToInt32(red * 255), Convert.ToInt32(green * 255), Convert.ToInt32(blue * 255)); } public static HSV ToHSV(Color rgb) { double red = rgb.R / 255.0; double green = rgb.G / 255.0; double blue = rgb.B / 255.0; var min = Math.Min(red, Math.Min(green, blue)); var max = Math.Max(red, Math.Max(green, blue)); var delta = max - min; double hue; double saturation = 0; var value = max; if (max != 0) saturation = delta / max; if (delta == 0) hue = 0; else { if (red == max) hue = (green - blue) / delta + (green < blue ? 6 : 0); else if (green == max) hue = 2 + (blue - red) / delta; else hue = 4 + (red - green) / delta; hue /= 6; } return new HSV { Hue = hue, Saturation = saturation, Value = value }; } public static Color UpSaturation(Color rgb, float increse = 0.2f) //make color more colored { if (rgb.R == rgb.G && rgb.G == rgb.B) return rgb; var hsv_color = ToHSV(rgb); hsv_color.Saturation = Math.Min(hsv_color.Saturation + increse, 1.00f); return hsv_color.ToRGB(); } } public class SmoothColor { public Color RGB { get { return Interpolate(); } set { clr = value; } } Color Interpolate() { clr_ = ColorInterpolator.InterpolateBetween(clr, clr_, smooth); return clr_; } private float smooth = 0.65f; //smooth private Color clr = new Color(); private Color clr_ = new Color(); static class ColorInterpolator { delegate byte ComponentSelector(Color color); static ComponentSelector _redSelector = color => color.R; static ComponentSelector _greenSelector = color => color.G; static ComponentSelector _blueSelector = color => color.B; public static Color InterpolateBetween(Color endPoint1, Color endPoint2, double lambda) { if (lambda < 0 || lambda > 1) throw new ArgumentOutOfRangeException("lambda"); if (endPoint1 != endPoint2) { return Color.FromArgb( InterpolateComponent(endPoint1, endPoint2, lambda, _redSelector), InterpolateComponent(endPoint1, endPoint2, lambda, _greenSelector), InterpolateComponent(endPoint1, endPoint2, lambda, _blueSelector) ); } return endPoint1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] static byte InterpolateComponent(Color end1, Color end2, double lambda, ComponentSelector selector) { return (byte)(selector(end1) + (selector(end2) - selector(end1)) * lambda); } } } } }