代码之家  ›  专栏  ›  技术社区  ›  Graviton

在C中生成颜色渐变#

  •  25
  • Graviton  · 技术社区  · 15 年前

    我这里的问题类似于 the question here 除了我和C一起工作。

    我有两种颜色,我有一个预先设定好的步骤。如何检索 Color 这是两者之间的梯度吗?

    这是我尝试过的方法,但不起作用:

    int argbMax = Color.Chocolate.ToArgb();
    int argbMin = Color.Blue.ToArgb();
    var colorList = new List<Color>();
    
    for(int i=0; i<size; i++)
    {
        var colorAverage= argbMin + (int)((argbMax - argbMin) *i/size);
        colorList.Add(Color.FromArgb(colorAverage));
    }
    

    如果您尝试上述代码,您会发现 argb 与颜色的视觉逐渐增加不一致。

    对此有什么想法吗?

    5 回复  |  直到 8 年前
        1
  •  28
  •   Community CDub    8 年前

    您将必须提取R、G、B组件,并分别对每个组件执行相同的线性插值,然后重新组合。

    int rMax = Color.Chocolate.R;
    int rMin = Color.Blue.R;
    // ... and for B, G
    var colorList = new List<Color>();
    for(int i=0; i<size; i++)
    {
        var rAverage = rMin + (int)((rMax - rMin) * i / size);
        var gAverage = gMin + (int)((gMax - gMin) * i / size);
        var bAverage = bMin + (int)((bMax - bMin) * i / size);
        colorList.Add(Color.FromArgb(rAverage, gAverage, bAverage));
    }
    
        2
  •  10
  •   Oliver    15 年前

    也许这个功能可以帮助:

    public IEnumerable<Color> GetGradients(Color start, Color end, int steps)
    {
        Color stepper = Color.FromArgb((byte)((end.A - start.A) / (steps - 1)),
                                       (byte)((end.R - start.R) / (steps - 1)),
                                       (byte)((end.G - start.G) / (steps - 1)),
                                       (byte)((end.B - start.B) / (steps - 1)));
    
        for (int i = 0; i < steps; i++)
        {
            yield return Color.FromArgb(start.A + (stepper.A * i),
                                        start.R + (stepper.R * i),
                                        start.G + (stepper.G * i),
                                        start.B + (stepper.B * i));
        }
    }
    
        3
  •  10
  •   jocull    12 年前

    奥利弗的回答非常接近…但在我的例子中,一些步进器的数字需要是负数。将步进器值转换为 Color 结构我的值从负值变为更高的值,例如-1变为类似254的值。我单独设置步骤值来解决这个问题。

    public static IEnumerable<Color> GetGradients(Color start, Color end, int steps)
    {
        int stepA = ((end.A - start.A) / (steps - 1));
        int stepR = ((end.R - start.R) / (steps - 1));
        int stepG = ((end.G - start.G) / (steps - 1));
        int stepB = ((end.B - start.B) / (steps - 1));
    
        for (int i = 0; i < steps; i++)
        {
            yield return Color.FromArgb(start.A + (stepA * i),
                                        start.R + (stepR * i),
                                        start.G + (stepG * i),
                                        start.B + (stepB * i));
        }
    }
    
        4
  •  7
  •   Steinwolfe    12 年前
        public static List<Color> GetGradientColors(Color start, Color end, int steps)
        {
            return GetGradientColors(start, end, steps, 0, steps - 1);
        }
    
        public static List<Color> GetGradientColors(Color start, Color end, int steps, int firstStep, int lastStep)
        {
            var colorList = new List<Color>();
            if (steps <= 0 || firstStep < 0 || lastStep > steps - 1)
                return colorList;
    
            double aStep = (end.A - start.A) / steps;
            double rStep = (end.R - start.R) / steps;
            double gStep = (end.G - start.G) / steps;
            double bStep = (end.B - start.B) / steps;
    
            for (int i = firstStep; i < lastStep; i++)
            {
                var a = start.A + (int)(aStep * i);
                var r = start.R + (int)(rStep * i);
                var g = start.G + (int)(gStep * i);
                var b = start.B + (int)(bStep * i);
                colorList.Add(Color.FromArgb(a, r, g, b));
            }
    
            return colorList;
        }
    
        5
  •  4
  •   DjCzermino    10 年前

    使用double而不是int:

    double stepA = ((end.A - start.A) / (double)(steps - 1));
    double stepR = ((end.R - start.R) / (double)(steps - 1));
    double stepG = ((end.G - start.G) / (double)(steps - 1));
    double stepB = ((end.B - start.B) / (double)(steps - 1));
    

    还有:

    yield return Color.FromArgb((int)start.A + (int)(stepA * step),
                                                (int)start.R + (int)(stepR * step),
                                                (int)start.G + (int)(stepG * step),
                                                (int)start.B + (int)(stepB * step));
    
    推荐文章