198 lines
6.0 KiB
C#
Executable File
198 lines
6.0 KiB
C#
Executable File
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Windows.UI;
|
|
|
|
namespace HueUWP
|
|
{
|
|
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));
|
|
}
|
|
}
|
|
}
|