【问题标题】:C#: Create a lighter/darker color based on a system color [duplicate]C#:根据系统颜色创建更浅/更深的颜色[重复]
【发布时间】:2010-10-22 12:46:18
【问题描述】:

复制

How do I adjust the brightness of a color?
How do I determine darker or lighter color variant of a given color?
Programmatically Lighten a Color


说我有

var c = Color.Red;

现在我想创建一个新的Color,它比那个颜色更亮或更暗。我怎样才能不费力气地做到这一点?

【问题讨论】:

    标签: c# colors


    【解决方案1】:

    ControlPaint.Light .Dark .DarkDark 等

    Color lightRed = ControlPaint.Light( Color.Red );
    

    【讨论】:

    • ControlPaint.Light 和 .Dark 是完美的:D 尤其是带有额外百分比浮动参数的东西。
    • 今天,我意识到.Net 框架非常庞大。因为我以前不知道 ControlPaint 类。但我只使用 3 方图像处理(如 AForge.net)。谢谢。
    • 可以将一个百分比传递给这个函数,尽管 MSDN 中没有给出关于这个百分比采用什么形式的线索,只是它是一个浮点数。
    • 我相信这仅适用于 Windows 表单(OP 未提及)
    • 如果是浮点数,那么它将是从 0 到 1。
    【解决方案2】:

    我最近blogged about this。主要思想是将给定的校正因子应用于每个颜色分量。以下静态方法使用指定的校正因子修改给定颜色的亮度,并生成该颜色的更暗或更亮变体:

    /// <summary>
    /// Creates color with corrected brightness.
    /// </summary>
    /// <param name="color">Color to correct.</param>
    /// <param name="correctionFactor">The brightness correction factor. Must be between -1 and 1. 
    /// Negative values produce darker colors.</param>
    /// <returns>
    /// Corrected <see cref="Color"/> structure.
    /// </returns>
    public static Color ChangeColorBrightness(Color color, float correctionFactor)
    {
        float red = (float)color.R;
        float green = (float)color.G;
        float blue = (float)color.B;
    
        if (correctionFactor < 0)
        {
            correctionFactor = 1 + correctionFactor;
            red *= correctionFactor;
            green *= correctionFactor;
            blue *= correctionFactor;
        }
        else
        {
            red = (255 - red) * correctionFactor + red;
            green = (255 - green) * correctionFactor + green;
            blue = (255 - blue) * correctionFactor + blue;
        }
    
        return Color.FromArgb(color.A, (int)red, (int)green, (int)blue);
    }
    

    【讨论】:

    • 很好的答案。优于 ControlPaint.Dark 或 ControlPaint.Light。 ControlPaint 方法不适用于非常小的百分比,它们有一些内置的最小值。您的代码甚至可以使用 0.1f。
    • @Pavel 如果我想要n 相同颜色的浅色调,我将如何使用你的算法?
    • @Geek,要生成给定颜色的 n 种较浅色调,只需使用范围 (0, 1] 内的不同校正因子执行算法,例如 0.05、0.10、0.15 等。
    • 不错。我可以对暗使用负数,对亮使用正数
    • @harveyt,要获得更深的颜色,最好使用稍微修改的公式。 The full article on my blog给出了详细的解释和代码示例。
    【解决方案3】:

    您也可以使用Lerp 函数来执行此操作。 XNA 里有,不过自己写很容易。

    有关 C# 实现,请参阅 my answer to this similar question

    该函数允许您这样做:

    // make red 50% lighter:
    Color.Red.Lerp( Color.White, 0.5 );
    
    // make red 75% darker:
    Color.Red.Lerp( Color.Black, 0.75 );
    
    // make white 10% bluer:
    Color.White.Lerp( Color.Blue, 0.1 );
    

    【讨论】:

      【解决方案4】:

      这些方法中的大多数确实会使颜色变暗,但它们会调整色调方式,因此结果看起来不太好。最佳答案是使用Rich Newman's HSLColor 类并调整亮度。

      public Color Darken(Color color, double darkenAmount) {
          HSLColor hslColor = new HSLColor(color);
          hslColor.Luminosity *= darkenAmount; // 0 to 1
          return hslColor;
      }
      

      【讨论】:

      • HSL 颜色空间允许更好的变亮和变暗例程,以及创建所有看起来“正确”的配色方案组件。 RGB 空间根本无法为这些类型的任务可靠地创建高质量的结果。
      • 我最终使用了它并对其进行了调整以增加亮度并使darkenAmount 参数(我将其命名为percentage)从color 变为黑色或白色。变暗:hslColor.Luminosity *= 1 - percentage; 和变亮:hslColor.Luminosity /= 1 - percentage;。感谢您的精彩回答。
      【解决方案5】:

      采用@Pavel's answer的核心方法,我准备了以下两个小扩展方法,以便更直观(至少对我而言)签名。

      public static Color LightenBy(this Color color, int percent)
      {
          return ChangeColorBrightness(color, percent/100.0);
      }
      
      public static Color DarkenBy(this Color color, int percent)
      {
          return ChangeColorBrightness(color, -1 * percent / 100.0); 
      }
      

      【讨论】:

        【解决方案6】:

        这里有一些 javascript 代码,用于使给定颜色变亮/变暗。您可以将其用作等效 C# 函数的基础

        它的工作原理是计算每个 RGB 分量与纯白色的距离,然后通过提供的因子调整该距离。新距离用于计算新颜色。 0到1之间的因子变暗,大于1的因子变亮

        function Darken( hexColor, factor )
            {   
                if ( factor < 0 ) factor = 0;
        
                var c = hexColor;
                if ( c.substr(0,1) == "#" )
                {
                    c = c.substring(1);
                }
        
                if ( c.length == 3 || c.length == 6 )
                {
                    var i = c.length / 3;
        
                    var f;  // the relative distance from white
        
                    var r = parseInt( c.substr(0, i ), 16 );
                    f = ( factor * r / (256-r) );
                    r = Math.floor((256 * f) / (f+1));
        
                    r = r.toString(16);
                    if ( r.length == 1 ) r = "0" + r;
        
                    var g = parseInt( c.substr(i, i), 16);
                    f = ( factor * g / (256-g) );
                    g = Math.floor((256 * f) / (f+1));
                    g = g.toString(16);
                    if ( g.length == 1 ) g = "0" + g;
        
                    var b = parseInt( c.substr( 2*i, i),16 );
                    f = ( factor * b / (256-b) );
                    b = Math.floor((256 * f) / (f+1));
                    b = b.toString(16);
                    if ( b.length == 1 ) b = "0" + b;
        
                    c =  r+g+b;
                 }   
        
                 return "#" + c;
        
            }
        

        【讨论】:

          【解决方案7】:

          您也可以根据需要简单地处理 RGB 百分比以使其更亮或更暗,下面是一个示例,说明如何使颜色比它更暗 x%:

          //_correctionfactory in percentage, e.g 50 = make it darker 50%
              private Color DarkerColor(Color color, float correctionfactory = 50f)
              {
                  const float hundredpercent = 100f;                        
                  return Color.FromArgb((int)(((float)color.R / hundredpercent) * correctionfactory),
                      (int)(((float)color.G / hundredpercent) * correctionfactory), (int)(((float)color.B / hundredpercent) * correctionfactory));
              }
          

          还有一件事,我们还可以将过程反转为更轻,只是我们得到 255 - RGB 的结果,然后将其乘以我们想要的百分比,如下例所示:

          private Color LighterColor(Color color, float correctionfactory = 50f)
              {
                  correctionfactory = correctionfactory / 100f;
                  const float rgb255 = 255f;
                  return Color.FromArgb((int)((float)color.R + ((rgb255 - (float)color.R) * correctionfactory)), (int)((float)color.G + ((rgb255 - (float)color.G) * correctionfactory)), (int)((float)color.B + ((rgb255 - (float)color.B) * correctionfactory))
                      );
              }
          

          希望对您有所帮助。

          【讨论】:

            【解决方案8】:

            我创建了一个这样做的网站colorglower.com您可以查看它以查看演示。

            这是我使用的 javascript 代码。

            function lighten(color) {
            
            // convert to decimal and change luminosity
            var luminosity = 0.01
            var computedColors = new Array();
            var newColor = "#",
                c, i, n, black = 0,
                white = 255;
            for (n = 0; n < 10; n++) {
                for (i = 0; i < 3; i++) {
                    c = parseInt(color.substr(i * 2, 2), 16);
                    c = Math.round(Math.min(Math.max(black, c + (luminosity * white)), white)).toString(16);
                    newColor += ("00" + c).substr(c.length);
                }
            
                computedColors[n] = newColor;
                var arrayUnique = checkIfArrayIsUnique(computedColors);
                if (arrayUnique == false) {
                    computedColors.pop();
                    break;
                }
            
                computedColors[n] = newColor;
                newColor = "#";
                luminosity += calcPercentage();
            }
            
            return computedColors;
            

            }

            此代码的作用是接收十六进制颜色,然后输出 10 个最浅的颜色版本并放入数组中。您可以将亮度更改为您喜欢的任何内容,以调整阴影百分比。要使颜色变暗,您只需更改:

            luminosity -= calcPercentage();
            

            【讨论】:

              【解决方案9】:

              使用 HSI 转换器库(搜索 google)。然后,调整 I 通道以获得更浅/更​​深的颜色。

              【讨论】:

                【解决方案10】:

                我更改了 Pavel Vladov 函数以修改甚至 RGB 分量,以获得 R/G/B 方向的任意组合的阴影:

                Public Function ChangeColorShades(color As Color, correctionFactor As Single, bR As Boolean, bG As Boolean, bB As Boolean) As Color
                
                
                    Dim red As Single = CSng(color.R)
                    Dim green As Single = CSng(color.G)
                    Dim blue As Single = CSng(color.B)
                
                    If (correctionFactor < 0) Then
                
                        correctionFactor = 1 + correctionFactor
                        If bR Then
                            red *= correctionFactor
                        End If
                        If bG Then
                            green *= correctionFactor
                        End If
                        If bB Then
                            blue *= correctionFactor
                        End If
                
                
                    Else
                        If bR Then
                            red = (255 - red) * correctionFactor + red
                        End If
                        If bG Then
                            green = (255 - green) * correctionFactor + green
                        End If
                        If bB Then
                            blue = (255 - blue) * correctionFactor + blue
                        End If
                
                    End If
                
                    Return color.FromArgb(color.A, CInt(red), CInt(green), CInt(blue))
                End Function
                

                【讨论】:

                • 问题标记为 C#
                猜你喜欢
                • 1970-01-01
                • 2012-08-03
                • 2021-11-29
                • 1970-01-01
                • 1970-01-01
                • 2017-05-17
                • 2012-09-26
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多