/// <summary>
/// 色彩空间转换
/// </summary>
public static class ColourConverter
{
public static bool RgbToCmyk(int red, int green, int blue, out int cyan, out int magenta, out int yellow, out int black)
{
cyan = 255 - red;
magenta = 255 - green;
yellow = 255 - blue;
black = cyan;
if (black > magenta)
{
black = magenta;
}
if (black > yellow)
{
black = yellow;
}
cyan -= black;
magenta -= black;
yellow -= black;
return true;
}
public static bool RgbToHsl(int red, int green, int blue, out double hue, out double saturation, out double luminosity)
{
double num = red / 255.0;
double num2 = green / 255.0;
double num3 = blue / 255.0;
hue = 0.0;
double val = Math.Min(num, num2);
val = Math.Min(val, num3);
double val2 = Math.Max(num, num2);
val2 = Math.Max(val2, num3);
double num4 = val2 - val;
luminosity = (val2 + val) / 2.0;
if (num4 <= double.Epsilon)
{
hue = 0.0;
saturation = 0.0;
}
else
{
if (luminosity < 0.5)
{
saturation = num4 / (val2 + val);
}
else
{
saturation = num4 / (2.0 - val2 - val);
}
double num5 = ((val2 - num) / 6.0 + num4 / 2.0) / num4;
double num6 = ((val2 - num2) / 6.0 + num4 / 2.0) / num4;
double num7 = ((val2 - num3) / 6.0 + num4 / 2.0) / num4;
if (num.Equals(val2))
{
hue = num7 - num6;
}
else if (num2.Equals(val2))
{
hue = 0.33333333333333331 + num5 - num7;
}
else if (num3.Equals(val2))
{
hue = 2.0 / 3.0 + num6 - num5;
}
if (hue < 0.0)
{
hue += 1.0;
}
if (hue > 1.0)
{
hue -= 1.0;
}
}
hue *= 100.0;
saturation *= 100.0;
luminosity *= 100.0;
return true;
}
public static bool RgbToLab(int red, int green, int blue, out double lightness, out double a, out double b)
{
lightness = 0.0;
a = 0.0;
b = 0.0;
if (!RgbToXyz(red, green, blue, out double x, out double y, out double z))
{
return false;
}
if (!XyzToLab(x, y, z, out lightness, out a, out b))
{
return false;
}
return true;
}
public static bool RgbToXyz(int red, int green, int blue, out double x, out double y, out double z)
{
double num = red / 255.0;
double num2 = green / 255.0;
double num3 = blue / 255.0;
num = (!(num > 0.04045)) ? (num / 12.92) : Math.Pow((num + 0.055) / 1.055, 2.4);
num2 = (!(num2 > 0.04045)) ? (num2 / 12.92) : Math.Pow((num2 + 0.055) / 1.055, 2.4);
num3 = (!(num3 > 0.04045)) ? (num3 / 12.92) : Math.Pow((num3 + 0.055) / 1.055, 2.4);
num *= 100.0;
num2 *= 100.0;
num3 *= 100.0;
x = num * 0.4124 + num2 * 0.3576 + num3 * 0.1805;
y = num * 0.2126 + num2 * 0.7152 + num3 * 0.0722;
z = num * 0.0193 + num2 * 0.1192 + num3 * 0.9505;
return true;
}
public static bool CmykToRgb(int cyan, int magenta, int yellow, int black, out int red, out int green, out int blue)
{
double num = cyan / 2.55;
double num2 = magenta / 2.55;
double num3 = yellow / 2.55;
double num4 = black / 2.55;
double num5 = num + num4;
double num6 = num2 + num4;
double num7 = num3 + num4;
if (num5 > 100.0)
{
num5 = 100.0;
}
if (num6 > 100.0)
{
num6 = 100.0;
}
if (num7 > 100.0)
{
num7 = 100.0;
}
red = (int)((100.0 - num5) * 255.0 / 100.0 + 0.5);
green = (int)((100.0 - num6) * 255.0 / 100.0 + 0.5);
blue = (int)((100.0 - num7) * 255.0 / 100.0 + 0.5);
return true;
}
public static bool CmykToHsl(int cyan, int magenta, int yellow, int black, out double hue, out double saturation, out double luminosity)
{
hue = 0.0;
saturation = 0.0;
luminosity = 0.0;
if (!CmykToRgb(cyan, magenta, yellow, black, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToHsl(red, green, blue, out hue, out saturation, out luminosity))
{
return false;
}
return true;
}
public static bool CmykToLab(int cyan, int magenta, int yellow, int black, out double lightness, out double a, out double b)
{
lightness = 0.0;
a = 0.0;
b = 0.0;
if (!CmykToRgb(cyan, magenta, yellow, black, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToLab(red, green, blue, out lightness, out a, out b))
{
return false;
}
return true;
}
public static bool CmykToXyz(int cyan, int magenta, int yellow, int black, out double x, out double y, out double z)
{
x = 0.0;
y = 0.0;
z = 0.0;
if (!CmykToRgb(cyan, magenta, yellow, black, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToXyz(red, green, blue, out x, out y, out z))
{
return false;
}
return true;
}
public static bool HslToRgb(double hue, double saturation, double luminosity, out int red, out int green, out int blue)
{
hue /= 100.0;
saturation /= 100.0;
luminosity /= 100.0;
if (saturation.Equals(0.0))
{
red = (int)(luminosity * 255.0 + 0.5);
green = (int)(luminosity * 255.0 + 0.5);
blue = (int)(luminosity * 255.0 + 0.5);
}
else
{
double num = (!(luminosity < 0.5)) ? (luminosity + saturation - saturation * luminosity) : (luminosity * (1.0 + saturation));
double var = 2.0 * luminosity - num;
red = (int)(255.0 * HueToRgb(var, num, hue + 0.33333333333333331) + 0.5);
green = (int)(255.0 * HueToRgb(var, num, hue) + 0.5);
blue = (int)(255.0 * HueToRgb(var, num, hue - 0.33333333333333331) + 0.5);
}
return true;
}
public static bool HslToCmyk(double hue, double saturation, double luminosity, out int cyan, out int magenta, out int yellow, out int black)
{
cyan = 0;
magenta = 0;
yellow = 0;
black = 0;
if (!HslToRgb(hue, saturation, luminosity, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToCmyk(red, green, blue, out cyan, out magenta, out yellow, out black))
{
return false;
}
return true;
}
public static bool HslToLab(double hue, double saturation, double luminosity, out double lightness, out double a, out double b)
{
lightness = 0.0;
a = 0.0;
b = 0.0;
if (!HslToRgb(hue, saturation, luminosity, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToLab(red, green, blue, out lightness, out a, out b))
{
return false;
}
return true;
}
public static bool HslToXyz(double hue, double saturation, double luminosity, out double x, out double y, out double z)
{
x = 0.0;
y = 0.0;
z = 0.0;
if (!HslToRgb(hue, saturation, luminosity, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToXyz(red, green, blue, out x, out y, out z))
{
return false;
}
return true;
}
public static bool LabToRgb(double lightness, double a, double b, out int red, out int green, out int blue)
{
red = 0;
green = 0;
blue = 0;
if (!LabToXyz(lightness, a, b, out double x, out double y, out double z))
{
return false;
}
if (!XyzToRgb(x, y, z, out red, out green, out blue))
{
return false;
}
return true;
}
public static bool LabToCmyk(double lightness, double a, double b, out int cyan, out int magenta, out int yellow, out int black)
{
cyan = 0;
magenta = 0;
yellow = 0;
black = 0;
if (!LabToRgb(lightness, a, b, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToCmyk(red, green, blue, out cyan, out magenta, out yellow, out black))
{
return false;
}
return true;
}
public static bool LabToHsl(double lightness, double a, double b, out double hue, out double saturation, out double luminosity)
{
hue = 0.0;
saturation = 0.0;
luminosity = 0.0;
if (!LabToRgb(lightness, a, b, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToHsl(red, green, blue, out hue, out saturation, out luminosity))
{
return false;
}
return true;
}
public static bool LabToXyz(double lightness, double a, double b, out double x, out double y, out double z)
{
double num = (lightness + 16.0) / 116.0;
double num2 = a / 500.0 + num;
double num3 = num - b / 200.0;
num = (!(Math.Pow(num, 3.0) > 0.008856)) ? ((num - 0.13793103448275862) / 7.787) : Math.Pow(num, 3.0);
num2 = (!(Math.Pow(num2, 3.0) > 0.008856)) ? ((num2 - 0.13793103448275862) / 7.787) : Math.Pow(num2, 3.0);
num3 = (!(Math.Pow(num3, 3.0) > 0.008856)) ? ((num3 - 0.13793103448275862) / 7.787) : Math.Pow(num3, 3.0);
x = 95.047 * num2;
y = 100.0 * num;
z = 108.883 * num3;
return true;
}
public static bool XyzToRgb(double x, double y, double z, out int red, out int green, out int blue)
{
double num = x / 100.0;
double num2 = y / 100.0;
double num3 = z / 100.0;
double num4 = num * 3.2406 + num2 * -1.5372 + num3 * -0.4986;
double num5 = num * -0.9689 + num2 * 1.8758 + num3 * 0.0415;
double num6 = num * 0.0557 + num2 * -0.204 + num3 * 1.057;
num4 = (!(num4 > 0.0031308)) ? (12.92 * num4) : (1.055 * Math.Pow(num4, 5.0 / 12.0) - 0.055);
num5 = (!(num5 > 0.0031308)) ? (12.92 * num5) : (1.055 * Math.Pow(num5, 5.0 / 12.0) - 0.055);
num6 = (!(num6 > 0.0031308)) ? (12.92 * num6) : (1.055 * Math.Pow(num6, 5.0 / 12.0) - 0.055);
red = (int)(num4 * 255.0);
green = (int)(num5 * 255.0);
blue = (int)(num6 * 255.0);
if (red < 0)
{
red = 0;
}
if (green < 0)
{
green = 0;
}
if (blue < 0)
{
blue = 0;
}
if (red > 255)
{
red = 255;
}
if (green > 255)
{
green = 255;
}
if (blue > 255)
{
blue = 255;
}
return true;
}
public static bool XyzToCmyk(double x, double y, double z, out int cyan, out int magenta, out int yellow, out int black)
{
cyan = 0;
magenta = 0;
yellow = 0;
black = 0;
if (!XyzToRgb(x, y, z, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToCmyk(red, green, blue, out cyan, out magenta, out yellow, out black))
{
return false;
}
return true;
}
public static bool XyzToHsl(double x, double y, double z, out double hue, out double saturation, out double luminosity)
{
hue = 0.0;
saturation = 0.0;
luminosity = 0.0;
if (!XyzToRgb(x, y, z, out int red, out int green, out int blue))
{
return false;
}
if (!RgbToHsl(red, green, blue, out hue, out saturation, out luminosity))
{
return false;
}
return true;
}
public static bool XyzToLab(double x, double y, double z, out double lightness, out double a, out double b)
{
double num = x / 95.047;
double num2 = y / 100.0;
double num3 = z / 108.883;
num = (!(num > 0.008856)) ? (7.787 * num + 0.13793103448275862) : Math.Pow(num, 0.33333333333333331);
num2 = (!(num2 > 0.008856)) ? (7.787 * num2 + 0.13793103448275862) : Math.Pow(num2, 0.33333333333333331);
num3 = (!(num3 > 0.008856)) ? (7.787 * num3 + 0.13793103448275862) : Math.Pow(num3, 0.33333333333333331);
lightness = 116.0 * num2 - 16.0;
a = 500.0 * (num - num2);
b = 200.0 * (num2 - num3);
return true;
}
public static double HueToRgb(double var1, double var2, double hue)
{
if (hue < 0.0)
{
hue += 1.0;
}
if (hue > 1.0)
{
hue -= 1.0;
}
if (6.0 * hue < 1.0)
{
return var1 + (var2 - var1) * 6.0 * hue;
}
if (2.0 * hue < 1.0)
{
return var2;
}
if (3.0 * hue < 2.0)
{
return var1 + (var2 - var1) * (2.0 / 3.0 - hue) * 6.0;
}
return var1;
}
}