2010-01-06 21 views
24

Mi pregunta aquí es similar a the question here, excepto que estoy trabajando con C#.Generar gradiente de color en C#

Tengo dos colores, y tengo unos pasos predefinidos. ¿Cómo recuperar una lista de Color que son los gradientes entre los dos?

Este es un enfoque que he intentado, pero no funcionó:

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)); 
} 

Si intenta el código anterior, se encuentra que un aumento gradual en argb no se corresponde con un aumento gradual visual en el color.

¿Alguna idea de esto?

Respuesta

25

Deberá extraer los componentes R, G, B y realizar la misma interpolación lineal en cada uno de ellos individualmente, luego recombinarlos.

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)); 
} 
9

Tal vez esta función puede ayudar: Respuesta

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)); 
    } 
} 
+0

Esto era muy cerca, pero tuve algunos valores de paso negativos que fueron romperlo. Publiqué mi solución alterada también. – jocull

6
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; 
    } 
7

de Oliver estaba muy cerca ... pero en mi caso algunos de mis números de pasos necesarios para ser negativo. Al convertir los valores paso a paso en una estructura Color, mis valores iban de valores negativos a valores más altos, p. -1 se convierte en algo así como 254. Configuro mis valores de paso individualmente para solucionar esto.

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)); 
    } 
} 
+0

Esto es súper simple, se ve increíble y funciona. Gracias :-) –

4

uso doble en vez de 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)); 

y:

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));