前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Openxml】颜色变化属性计算

【Openxml】颜色变化属性计算

作者头像
ryzenWzd
发布2022-06-14 16:03:03
8350
发布2022-06-14 16:03:03
举报
文章被收录于专栏:WPF

Openxml的颜色变化属性

目前Openxml存在颜色变化属性如下:

参数

说明

Hue

色调(色相)

HueModulate

色调调制,百分比

HueOffset

色调偏移量,角度值

Saturation

饱和度

SaturationModulation

饱和度调制,百分比

SaturationOffset

饱和度偏移量

Luminance

亮度

LuminanceModulation

亮度调制,百分比

LuminanceOffset

亮度偏移量

Alpha

Alpha

AlphaModulation

Alpha 调制,百分比

AlphaOffset

Alpha 偏移量

Red

红色

RedModulation

红色调制,百分比

RedOffset

红色偏移量

Blue

蓝色

BlueModification

蓝色调制

BlueOffse

蓝色偏移量,百分比

Green

绿色

GreenModification

绿色调制,百分比

GreenOffset

绿色偏移量

Complement

补充

Gamma

伽玛

Gray

灰色

Inverse

反函数

Inverse Gamma

反函数伽玛

Shade

底纹,百分比

Tint

底纹,百分比

RGB和Hsl的相互转换

其中有关RGB和Hsl的相互转换的公式如下:

RGB转Hsl公式如下:

Hsl转RGB公式如下:

其中涉及到有Hsl计算的有以下九个属性:

  • Hue、HueModulate、HueOffset
  • Saturation、SaturationModulation、SaturationOffset
  • Luminance、LuminanceModulation、LuminanceOffset

那么我们开始写代码:

定义RGB的类:

代码语言:javascript
复制
    /// <summary>
    /// 用 A R G B 表示的颜色
    /// </summary>
    public class ARgbColor
    {
        /// <summary>
        /// 创建 A R G B 颜色
        /// </summary>
        public ARgbColor()
        {
        }

        /// <summary>
        /// 创建 A R G B 颜色
        /// </summary>
        /// <param name="a"></param>
        /// <param name="r"></param>
        /// <param name="g"></param>
        /// <param name="b"></param>
        public ARgbColor(byte a, byte r, byte g, byte b)
        {
            A = a;
            R = r;
            G = g;
            B = b;
        }

        /// <summary>
        /// 表示透明色
        /// </summary>
        public byte A { set; get; }

        /// <summary>
        /// 表示红色
        /// </summary>
        public byte R { set; get; }

        /// <summary>
        /// 表示绿色
        /// </summary>
        public byte G { set; get; }

        /// <summary>
        /// 表示蓝色
        /// </summary>
        public byte B { set; get; }

    }

定义颜色变化相关类ColorTransform,并且定义RGB和Hsl的相互转换逻辑方法:

代码语言:javascript
复制
    /// <summary>
    ///     处理颜色之间的变换,调整,格式转换
    /// </summary>
    public static class ColorTransform
    {

        /// <summary>
        ///  将<see cref="Color" />的数据转换为Hsl
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static (Degree hue, Percentage sat, Percentage lum, byte alpha) ColorToHsl(Color color)
        {
            var max = System.Math.Max(color.R, System.Math.Max(color.G, color.B));
            var min = System.Math.Min(color.R, System.Math.Min(color.G, color.B));
            var delta = max - min;
            var l = Percentage.FromDouble((max + min) / 2.0 / 255.0);
            var h = Degree.FromDouble(0);
            var s = Percentage.Zero;

            if (delta > 0)
            {
                s = l < Percentage.FromDouble(0.5)
                    ? Percentage.FromDouble((max - min) * 1.0 / (max + min))
                    : Percentage.FromDouble((max - min) * 1.0 / (2 * 255 - max - min));

                if (max == color.R)
                {
                    h = Degree.FromDouble((0 + (color.G - color.B) * 1.0 / delta) * 60);
                }
                else if (max == color.G)
                {
                    h = Degree.FromDouble((2 + (color.B - color.R) * 1.0 / delta) * 60);
                }
                else
                {
                    h = Degree.FromDouble((4 + (color.R - color.G) * 1.0 / delta) * 60);
                }
            }

            return (h, s, l, color.A);
        }

    }

            /// <summary>
        ///     将Hsl的数据转换为<see cref="Color" />
        /// </summary>
        /// <param name="hue">色相</param>
        /// <param name="saturation">饱和度</param>
        /// <param name="lightness">亮度</param>
        /// <param name="a">透明度</param>
        /// <returns></returns>
        public static Color HslToColor(Degree hue, Percentage saturation, Percentage lightness, byte a = 0xFF)
        {
            var color = new Color { A = a };

            var hueValue = hue.DoubleValue;
            var saturationValue = saturation.DoubleValue;
            var lightnessValue = lightness.DoubleValue;

            var c = (1 - System.Math.Abs(2 * lightnessValue - 1)) * saturationValue;
            var x = c * (1 - System.Math.Abs((hueValue / 60) % 2 - 1));
            var m = lightnessValue - c / 2;

            var r = 0d;
            var g = 0d;
            var b = 0d;

            if (hueValue is >= 0 and < 60)
            {
                r = c;
                g = x;
                b = 0;
            }

            if (hueValue is >= 60 and < 120)
            {
                r = x;
                g = c;
                b = 0;
            }

            if (hueValue is >= 120 and < 180)
            {
                r = 0;
                g = c;
                b = x;
            }

            if (hueValue is >= 180 and < 240)
            {
                r = 0;
                g = x;
                b = c;
            }

            if (hueValue is >= 240 and < 300)
            {
                r = x;
                g = 0;
                b = c;
            }

            if (hueValue is >= 300 and < 360)
            {
                r = c;
                g = 0;
                b = x;
            }

            color.R = (byte) ((r + m) * 255);
            color.G = (byte) ((g + m) * 255);
            color.B = (byte) ((b + m) * 255);

            return color;
        }

然后我们来写真正处理Openxml的Hsl相关属性逻辑:

代码语言:javascript
复制
       /// <summary>
        ///     将<see cref="RgbColorModelHex" />转换为<see cref="Color" />
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static Color? ToColor(this RgbColorModelHex color)
        {
            if (color.Val is not null)
            {
                if (uint.TryParse(color.Val.Value, NumberStyles.HexNumber, null, out var result))
                {
                    var solidColor = result.HexToColor();
                    var modifiedColor = ColorTransform.AppendColorModify(solidColor, color.ChildElements);
                    return modifiedColor;
                }
            }

            return null;
        }


        private static Color HexToColor(this uint rgb)
        {
            var color = new Color();
            const int maxByte = 0xff;

            color.B = (byte) (rgb & maxByte);
            color.G = (byte) ((rgb >> 8) & maxByte);
            color.R = (byte) ((rgb >> 16) & maxByte);
            color.A = 0xFF;

            return color;
        }

        /// <summary>
        /// 给颜色叠加转换
        /// </summary>
        /// <param name="color"></param>
        /// <param name="list"></param>
        /// <returns></returns>
        public static Color AppendColorModify(ARgbColor color, OpenXmlElementList list)
        {
            var updatedColor = color;
            foreach (var element in list)
            {
                if (element is Hue hue)
                {
                    updatedColor = HandleHue(updatedColor, hue, null, null);
                    continue;
                }

                if (element is HueModulation hueModulation)
                {
                    updatedColor = HandleHue(updatedColor, null, hueModulation, null);
                    continue;
                }

                if (element is HueOffset hueOffset)
                {
                    updatedColor = HandleHue(updatedColor, null, null, hueOffset);
                    continue;
                }

                if (element is Saturation saturation)
                {
                    updatedColor = HandleSaturation(updatedColor, saturation, null, null);
                    continue;
                }

                if (element is SaturationModulation saturationModulation)
                {
                    updatedColor = HandleSaturation(updatedColor, null, saturationModulation, null);
                    continue;
                }

                if (element is SaturationOffset saturationOffset)
                {
                    updatedColor = HandleSaturation(updatedColor, null, null, saturationOffset);
                    continue;
                }

                if (element is Luminance luminance)
                {
                    updatedColor = HandleLuminance(updatedColor, luminance, null, null);
                    continue;
                }

                if (element is LuminanceModulation luminanceModulation)
                {
                    updatedColor = HandleLuminance(updatedColor, null, luminanceModulation, null);
                    continue;
                }

                if (element is LuminanceOffset luminanceOffset)
                {
                    updatedColor = HandleLuminance(updatedColor, null, null, luminanceOffset);
                    continue;
                }
            }


        private static Color HandleHue(Color color, Hue? hueElement, HueModulation? hueModElement,
            HueOffset? hueOffsetElement)
        {
            if (hueElement is null && hueModElement is null && hueOffsetElement is null)
            {
                return color;
            }

            var updatedColor = HandleHslCore(color, hueElement: hueElement, hueModElement: hueModElement, hueOffsetElement: hueOffsetElement);

            return updatedColor;
        }

        private static Color HandleSaturation(Color color, Saturation? satElement, SaturationModulation? satModElement,
            SaturationOffset? satOffsetElement)
        {
            if (satElement is null && satModElement is null && satOffsetElement is null)
            {
                return color;
            }

            var updatedColor = HandleHslCore(color, satElement: satElement, satModElement: satModElement, satOffsetElement: satOffsetElement);

            return updatedColor;
        }

        private static Color HandleLuminance(Color color, Luminance? lumElement, LuminanceModulation? lumModElement,
            LuminanceOffset? lumOffsetElement)
        {
            if (lumElement is null && lumModElement is null && lumOffsetElement is null)
            {
                return color;
            }

            var updatedColor = HandleHslCore(color, lumElement: lumElement, lumModElement: lumModElement, lumOffsetElement: lumOffsetElement);

            return updatedColor;
        }


        private static Color HandleHslCore(Color color,
            Hue? hueElement = null, HueModulation? hueModElement = null, HueOffset? hueOffsetElement = null,
            Saturation? satElement = null, SaturationModulation? satModElement = null, SaturationOffset? satOffsetElement = null,
            Luminance? lumElement = null, LuminanceModulation? lumModElement = null, LuminanceOffset? lumOffsetElement = null)
        {
            if (hueElement is null && hueModElement is null && hueOffsetElement is null
                && satElement is null && satModElement is null && satOffsetElement is null
                && lumElement is null && lumModElement is null && lumOffsetElement is null)
            {
                return color;
            }

            var (hue, sat, lum, alpha) = ColorToHsl(color);

            var hueElementVal = hueElement?.Val;
            var hueValue = hueElementVal is not null ? new Angle(hueElementVal).ToDegreeValue() : hue.DoubleValue;
            var satElementVal = satElement?.Val;
            var satValue = satElementVal is not null ? new Percentage(satElementVal).DoubleValue : sat.DoubleValue;
            var lumElementVal = lumElement?.Val;
            var lumValue = lumElementVal is not null ? new Percentage(lumElementVal).DoubleValue : lum.DoubleValue;

            var hueModElementVal = hueModElement?.Val;
            var hueModValue = hueModElementVal is not null && hueModElementVal.HasValue
                ? new Percentage(hueModElementVal)
                : Percentage.FromDouble(1);
            var satModElementVal = satModElement?.Val;
            var satModValue = satModElementVal is not null && satModElementVal.HasValue
                ? new Percentage(satModElementVal)
                : Percentage.FromDouble(1);
            var lumModElementVal = lumModElement?.Val;
            var lumModValue = lumModElementVal is not null && lumModElementVal.HasValue
                ? new Percentage(lumModElementVal)
                : Percentage.FromDouble(1);

            var hueOffsetVal = hueOffsetElement?.Val;
            var hueOffset = hueOffsetVal is not null && hueOffsetVal.HasValue
                ? new Angle(hueOffsetVal).ToDegreeValue()
                : new Angle(0).ToDegreeValue();
            var saturationOffsetVal = satOffsetElement?.Val;
            var saturationOffset = saturationOffsetVal is not null && saturationOffsetVal.HasValue
                ? new Percentage(saturationOffsetVal)
                : Percentage.Zero;
            var lumOffsetElementVal = lumOffsetElement?.Val;
            var lumOffset = lumOffsetElementVal is not null && lumOffsetElementVal.HasValue
                ? new Percentage(lumOffsetElementVal)
                : Percentage.Zero;

            var hueResult = hueValue * hueModValue.DoubleValue + hueOffset;
            hue = Degree.FromDouble(hueResult);

            var satResult = satValue * satModValue.DoubleValue + saturationOffset.DoubleValue;
            sat = Percentage.FromDouble(satResult);
            sat = sat > Percentage.FromDouble(1) ? Percentage.FromDouble(1) : sat;
            sat = sat < Percentage.Zero ? Percentage.Zero : sat;

            var lumResult = lumValue * lumModValue.DoubleValue + lumOffset.DoubleValue;
            lum = Percentage.FromDouble(lumResult);
            lum = lum > Percentage.FromDouble(1) ? Percentage.FromDouble(1) : lum;
            lum = lum < Percentage.Zero ? Percentage.Zero : lum;

            return HslToColor(hue, sat, lum, alpha);

        }

处理RGB相关属性

涉及到RGB相关的Openxml属性如下:

  • 透明度:Alpha、AlphaModulation、AlphaOffset
  • RGB的红色:Red、RedModulation、RedOffset
  • RGB的蓝色:Blue、BlueModulation、BlueOffset
  • RGB的绿色:Green、GreenModulation、GreenOffset
  • RGB的反函数:Inverse
  • RGB的补码: Complement
  • RGB的伽玛校正和反伽玛矫正: Gamma、InverseGamma
  • RGB的灰阶(灰度):Gray
处理透明度

以下为处理透明度的逻辑代码:

代码语言:javascript
复制
        private static Color HandleAlphaModify(Color color, Alpha? alphaElement, AlphaModulation? alphaModulation, AlphaOffset? alphaOffset)
        {
            if (alphaElement is null && alphaModulation is null && alphaOffset is null)
            {
                return color;
            }

            var alphaValue = alphaElement?.Val;
            var modulationVal = alphaModulation?.Val;
            var offsetVal = alphaOffset?.Val;

            var alpha = alphaValue is not null && alphaValue.HasValue
                ? new Percentage(alphaValue)
                : Percentage.FromDouble(1);

            var mod = modulationVal is not null && modulationVal.HasValue
                ? new Percentage(modulationVal)
                : Percentage.FromDouble(1);

            var off = offsetVal is not null && offsetVal.HasValue
                ? new Percentage(offsetVal)
                : Percentage.Zero;


            var alphaResult = alpha.DoubleValue * mod.DoubleValue + off.DoubleValue;
            color.A = (byte) (color.A * alphaResult);


            return color;
        }        
处理RGB的红色、蓝色、绿色

以下为处理RGB的红色、蓝色、绿色的逻辑代码:

代码语言:javascript
复制
        private static Color HandleRgb(Color color, Red? redElement, Green? greenElement, Blue? blueElement)
        {
            if (redElement is null && greenElement is null && blueElement is null)
            {
                return color;
            }

            var updatedColor = HandleRgbCore(color, redElement: redElement, greenElement: greenElement,
                blueElement: blueElement);


            return updatedColor;
        }
        private static Color HandleRgbModulation(Color color, RedModulation? redModulationElement, GreenModulation? greenModulationElement, BlueModulation? blueModulationElement)
        {
            if (redModulationElement is null && greenModulationElement is null && blueModulationElement is null)
            {
                return color;
            }

            var updatedColor = HandleRgbCore(color, redModulationElement: redModulationElement,
                greenModulationElement: greenModulationElement, blueModulationElement: blueModulationElement);


            return updatedColor;
        }


        private static Color HandleRgbOffset(Color color, RedOffset? redOffsetElement, GreenOffset? greenOffsetElement, BlueOffset? blueOffsetElement)
        {
            if (redOffsetElement is null && blueOffsetElement is null && greenOffsetElement is null)
            {
                return color;
            }

            var updatedColor = HandleRgbCore(color, redOffsetElement: redOffsetElement,
                greenOffsetElement: greenOffsetElement, blueOffsetElement: blueOffsetElement);


            return updatedColor;
        }


         private static Color HandleRgbCore(Color color,
            Red? redElement = null, Green? greenElement = null, Blue? blueElement = null,
            RedModulation? redModulationElement = null, GreenModulation? greenModulationElement = null, BlueModulation? blueModulationElement = null,
            RedOffset? redOffsetElement = null, GreenOffset? greenOffsetElement = null, BlueOffset? blueOffsetElement = null)
        {
            if (redElement is null && greenElement is null && blueElement is null
                && redModulationElement is null && greenModulationElement is null && blueModulationElement is null
                && redOffsetElement is null && greenOffsetElement is null && blueOffsetElement is null)
            {
                return color;
            }

            var updatedColor = color;

            var redModulationValue = redModulationElement?.Val;
            var redMod = redModulationValue is not null ? new Percentage(redModulationValue) : Percentage.FromDouble(1);

            var greenModulationValue = greenModulationElement?.Val;
            var greenMod = greenModulationValue is not null ? new Percentage(greenModulationValue) : Percentage.FromDouble(1);

            var blueModulationValue = blueModulationElement?.Val;
            var blueMod = blueModulationValue is not null ? new Percentage(blueModulationValue) : Percentage.FromDouble(1);

            var redOffsetValue = redOffsetElement?.Val;
            var redOffset = redOffsetValue is not null ? new Percentage(redOffsetValue) : Percentage.FromDouble(0);

            var greenOffsetValue = greenOffsetElement?.Val;
            var greenOffset = greenOffsetValue is not null ? new Percentage(greenOffsetValue) : Percentage.FromDouble(0);

            var blueOffsetValue = blueOffsetElement?.Val;
            var blueOffset = blueOffsetValue is not null ? new Percentage(blueOffsetValue) : Percentage.FromDouble(0);


            var linearR = SRgbToLinearRgb(updatedColor.R / 255.0);
            var linearG = SRgbToLinearRgb(updatedColor.G / 255.0);
            var linearB = SRgbToLinearRgb(updatedColor.B / 255.0);

            var redValue = redElement?.Val;
            var red = redValue is not null ? new Percentage(redValue).DoubleValue : linearR;

            var greenValue = greenElement?.Val;
            var green = greenValue is not null ? new Percentage(greenValue).DoubleValue : linearG;

            var blueValue = blueElement?.Val;
            var blue = blueValue is not null ? new Percentage(blueValue).DoubleValue : linearB;

            var redResult = red * redMod.DoubleValue + redOffset.DoubleValue;
            var greenResult = green * greenMod.DoubleValue + greenOffset.DoubleValue;
            var blueResult = blue * blueMod.DoubleValue + blueOffset.DoubleValue;


            var r = redResult < 0 ? 0 : redResult > 1 ? 1 : redResult;
            var g = greenResult < 0 ? 0 : greenResult > 1 ? 1 : greenResult;
            var b = blueResult < 0 ? 0 : blueResult > 1 ? 1 : blueResult;
            updatedColor.R = (byte) System.Math.Round(255 * LinearRgbToSRgb(r));
            updatedColor.G = (byte) System.Math.Round(255 * LinearRgbToSRgb(g));
            updatedColor.B = (byte) System.Math.Round(255 * LinearRgbToSRgb(b));

            return updatedColor;
        }

        /// <summary>
        /// https://en.wikipedia.org/wiki/SRGB#The_forward_transformation_.28CIE_xyY_or_CIE_XYZ_to_sRGB.29
        /// </summary>
        /// <param name="sRgb"></param>
        /// <returns></returns>
        private static double SRgbToLinearRgb(double sRgb)
        {
            if (sRgb <= 0.04045) return sRgb / 12.92;

            return System.Math.Pow((sRgb + 0.055) / 1.055, 2.4);
        }
RGB的反函数

以下为处理RGB的反函数的逻辑代码:

代码语言:javascript
复制
        private static Color HandleInverse(Color color, Inverse? inverseElement)
        {
            var updatedColor = color;
            if (inverseElement != null)
            {
                var linearR = SRgbToLinearRgb(updatedColor.R / 255.0);
                var linearG = SRgbToLinearRgb(updatedColor.G / 255.0);
                var linearB = SRgbToLinearRgb(updatedColor.B / 255.0);
                var r = System.Math.Abs(1.0 - linearR);
                var g = System.Math.Abs(1.0 - linearG);
                var b = System.Math.Abs(1.0 - linearB);
                updatedColor.R = (byte) System.Math.Round(255 * LinearRgbToSRgb(r));
                updatedColor.G = (byte) System.Math.Round(255 * LinearRgbToSRgb(g));
                updatedColor.B = (byte) System.Math.Round(255 * LinearRgbToSRgb(b));
            }

            return updatedColor;
        }
RGB的补码

以下为处理RGB的补码的逻辑代码:

代码语言:javascript
复制
        private static Color HandleComplement(Color color, Complement? complementElement)
        {
            var updatedColor = color;
            if (complementElement != null)
            {
                var r = updatedColor.B;
                var g = updatedColor.R + updatedColor.B - updatedColor.G;
                var b = updatedColor.R;
                updatedColor.R = r;
                updatedColor.G = (byte) g;
                updatedColor.B = b;
            }

            return updatedColor;
        }
RGB的伽玛校正和反伽玛矫正
伽玛校正

 实际上就是显示器的非线性特性让亮度在我们眼中看起来更好, 但是在渲染时反而会因此导致问题. 我们的渲染计算都是在伽马值为 1 的理想线性空间进行的,而显示器的非线性则是伽马值为 2.2计算的即为输入值的pow 2.2,伽马校正的思路就是在颜色被输送到显示器之前, 我们先对其进行 pow 1/2.2 的逆运算以抵消显示器的作用

因此计算伽玛校正的逻辑代码如下:

代码语言:javascript
复制
        /// <summary>
        /// 对于sRGB的伽玛校正,也就是 1/2.2的幂运算
        /// </summary>
        /// <param name="color"></param>
        /// <param name="gammaElement"></param>
        /// <returns></returns>
        private static Color HandleGamma(Color color, Gamma? gammaElement)
        {
            var updatedColor = color;
            if (gammaElement != null)
            {
                var r = System.Math.Pow(updatedColor.R / 255.0, 1 / 2.2);
                var g = System.Math.Pow(updatedColor.G / 255.0, 1 / 2.2);
                var b = System.Math.Pow(updatedColor.B / 255.0, 1 / 2.2);
                updatedColor.R = (byte) System.Math.Round(255 * r);
                updatedColor.G = (byte) System.Math.Round(255 * g);
                updatedColor.B = (byte) System.Math.Round(255 * b);
            }

            return updatedColor;
        }

而对于反伽玛校正,则其指数为2.2,代码如下:

代码语言:javascript
复制
        /// <summary>
        /// 对于sRGB的反伽玛校正,也就是2.2的幂运算
        /// </summary>
        /// <param name="color"></param>
        /// <param name="inverseGammaElement"></param>
        /// <returns></returns>
        private static Color HandleInverseGamma(Color color, InverseGamma? inverseGammaElement)
        {
            var updatedColor = color;
            if (inverseGammaElement != null)
            {
                var r = System.Math.Pow(updatedColor.R / 255.0, 2.2);
                var g = System.Math.Pow(updatedColor.G / 255.0, 2.2);
                var b = System.Math.Pow(updatedColor.B / 255.0, 2.2);
                updatedColor.R = (byte) System.Math.Round(255 * r);
                updatedColor.G = (byte) System.Math.Round(255 * g);
                updatedColor.B = (byte) System.Math.Round(255 * b);
            }

            return updatedColor;
        }
RGB的灰阶

不同的RGB空间,灰阶的计算公式有所不同,常见的几种RGB空间的计算灰阶的公式如下:

代码语言:javascript
复制
//简化 sRGB IEC61966-2.1 [gamma=2.20]
Gray = (R^2.2 * 0.2126  + G^2.2  * 0.7152  + B^2.2  * 0.0722)^(1/2.2)

//Adobe RGB (1998) [gamma=2.20]
Gray = (R^2.2 * 0.2973  + G^2.2  * 0.6274  + B^2.2  * 0.0753)^(1/2.2)

//Apple RGB [gamma=1.80]
Gray = (R^1.8 * 0.2446  + G^1.8  * 0.6720  + B^1.8  * 0.0833)^(1/1.8)

//ColorMatch RGB [gamma=1.8]
Gray = (R^1.8 * 0.2750  + G^1.8  * 0.6581  + B^1.8  * 0.0670)^(1/1.8)

//简化 KODAK DC Series Digital Camera [gamma=2.2]
Gray = (R^2.2 * 0.2229  + G^2.2  * 0.7175  + B^2.2  * 0.0595)^(1/2.2)

而我们选择了灰度系数2.2,即伽马值为2.2的sRGB的计算公式,那么逻辑代码如下:

代码语言:javascript
复制
        /// <summary>
        /// 对于sRGB的灰阶计算
        /// </summary>
        /// <param name="color"></param>
        /// <param name="grayElement"></param>
        /// <returns></returns>
        /// sRGB IEC61966-2.1 [gamma=2.20]:sRGB计算灰阶:Gray = (R^2.2 * 0.2126  + G^2.2  * 0.7152  + B^2.2  * 0.0722)^(1/2.2)
        private static Color HandleGray(Color color, Gray? grayElement)
        {
            var updatedColor = color;
            if (grayElement != null)
            {
                var gray = System.Math.Pow(
                          System.Math.Pow(updatedColor.R, 2.2) * 0.2126 +
                          System.Math.Pow(updatedColor.G, 2.2) * 0.7152 +
                          System.Math.Pow(updatedColor.B, 2.2) * 0.0722,
                          1 / 2.2);

                var grayResult = (byte) System.Math.Round(gray);

                updatedColor.R = grayResult;
                updatedColor.G = grayResult;
                updatedColor.B = grayResult;
            }

            return updatedColor;
        }

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Openxml的颜色变化属性
  • RGB和Hsl的相互转换
  • 处理RGB相关属性
    • 处理透明度
      • 处理RGB的红色、蓝色、绿色
        • RGB的反函数
          • RGB的补码
            • RGB的伽玛校正和反伽玛矫正
              • 伽玛校正
            • RGB的灰阶
            • 参考
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档