Files
huehuehue/HueUWP/Helpers/ColorUtil.cs
T

199 lines
5.9 KiB
C#

using HueUWP.Lights;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI;
namespace HueUWP.Helpers
{
public static class ColorUtil
{
public static Color getColor(Light light)
{
double hue = ((double)light.Hue * 360.0f) / 65535.0f;
double sat = (double)light.Saturation / 255.0f;
double val = (double)light.Brightness/ 255.0f;
int r, g, b;
HsvToRgb(hue, sat, val, out r, out g, out b);
return Color.FromArgb(255, Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b));
}
public static void RGBtoHSV(double r, double g, double b, out double h, out double s, out double v)
{
double min, max, delta;
min = Math.Min(r, Math.Min(g, b));
max = Math.Max(r, Math.Max(g, b));
v = max; // v
delta = max - min;
if (max != 0)
s = delta / max; // s
else
{
// r = g = b = 0 // s = 0, v is undefined
s = 0;
h = -1;
return;
}
if (r == max)
h = (g - b) / delta; // between yellow & magenta
else if (g == max)
h = 2 + (b - r) / delta; // between cyan & yellow
else
h = 4 + (r - g) / delta; // between magenta & cyan
h *= 60; // degrees
if (h < 0)
h += 360;
}
private static void HsvToRgb(double h, double S, double V, out int r, out int g, out int b)
{
double H = h;
while (H < 0)
{
H += 360;
}
while (H >= 360)
{
H -= 360;
}
double R, G, B;
if (V <= 0)
R = G = B = 0;
else if (S <= 0)
R = G = B = V;
else
{
double hf = H / 60.0;
int i = (int)Math.Floor(hf);
double f = hf - i;
double pv = V * (1 - S);
double qv = V * (1 - S * f);
double tv = V * (1 - S * (1 - f));
switch (i)
{
// Red is the dominant color
case 0:
R = V;
G = tv;
B = pv;
break;
// Green is the dominant color
case 1:
R = qv;
G = V;
B = pv;
break;
case 2:
R = pv;
G = V;
B = tv;
break;
// Blue is the dominant color
case 3:
R = pv;
G = qv;
B = V;
break;
case 4:
R = tv;
G = pv;
B = V;
break;
// Red is the dominant color
case 5:
R = V;
G = pv;
B = qv;
break;
// Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here.
case 6:
R = V;
G = tv;
B = pv;
break;
case -1:
R = V;
G = pv;
B = qv;
break;
// The color is not defined, we should throw an error.
default:
//LFATAL("i Value error in Pixel conversion, Value is %d", i);
R = G = B = V; // Just pretend its black/white
break;
}
}
r = Clamp((int)(R * 255.0));
g = Clamp((int)(G * 255.0));
b = Clamp((int)(B * 255.0));
}
private static int Clamp(int i)
{
if (i < 0) return 0;
if (i > 255) return 255;
return i;
}
public static Color HsvToRgb(double hue, double sat, double val)
{
double h = ((double)hue * 360.0f) / 65535.0f;
double s = (double)sat / 255.0f;
double v = (double)val / 255.0f;
int hi = (int)Math.Floor(h / 60.0) % 6;
double f = (h / 60.0) - Math.Floor(h / 60.0);
double p = v * (1.0 - s);
double q = v * (1.0 - (f * s));
double t = v * (1.0 - ((1.0 - f) * s));
Color ret;
switch (hi)
{
case 0:
ret = GetRgb(v, t, p);
break;
case 1:
ret = GetRgb(q, v, p);
break;
case 2:
ret = GetRgb(p, v, t);
break;
case 3:
ret = GetRgb(p, q, v);
break;
case 4:
ret = GetRgb(t, p, v);
break;
case 5:
ret = GetRgb(v, p, q);
break;
default:
ret = Color.FromArgb(0xFF, 0x00, 0x00, 0x00);
break;
}
return ret;
}
public static Color GetRgb(double r, double g, double b)
{
return Color.FromArgb(255, (byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));
}
}
}