mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
193 lines
6.2 KiB
C#
193 lines
6.2 KiB
C#
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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
} |