C# 色彩空间转换

C# 色彩空间转换助手

/// <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;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值