Como faço para determinar mais claras ou escuras variante de cor de uma determinada cor?

StackOverflow https://stackoverflow.com/questions/97646

  •  01-07-2019
  •  | 
  •  

Pergunta

Dada uma cor fonte de qualquer matiz pelo sistema ou usuário, eu gostaria de um algoritmo simples que posso usar para trabalhar para fora uma mais clara ou escura variantes da cor selecionada. Semelhante aos efeitos usados ??no Windows Live Messenger para denominar a interface do usuário.

A linguagem é C # com .net 3.5.

Respondendo ao comentário: Formato de cor é (Alpha) RGB. Com valores como bytes ou carros alegóricos.

resposta Marcação : Para o contexto do meu uso (alguns efeitos simples UI), a resposta que eu estou marcação como aceite é realmente o mais simples para este contexto. No entanto, eu desisti de votos para as respostas mais complexas e precisas também. Qualquer um que faz operações de cor mais avançados e encontrar esta discussão no futuro deve definitivamente verificar os para fora. Graças SO. :)

Foi útil?

Solução

basta multiplicar o RGB valores pela quantidade que você deseja modificar o nível de. Se uma das cores já está no valor máximo, então você não pode torná-lo mais brilhante (usando HSV matemática de qualquer maneira.)

Isto dá exatamente o mesmo resultado com muito menos matemática como a mudança para HSV e, em seguida, modificando V. Isto dá o mesmo resultado que a mudança para HSL e, em seguida, modificando L, contanto que você não quer começar a perder saturação.

Outras dicas

Na XNA há a Color.Lerp método estático que faz isso como a diferença entre duas cores.

Lerp é uma operação matemática entre dois carros alegóricos que altera o valor do primeiro por uma razão entre a diferença entre eles.

Aqui está um método de extensão para fazê-lo a um float:

public static float Lerp( this float start, float end, float amount)
{
    float difference = end - start;
    float adjusted = difference * amount;
    return start + adjusted;
}

Assim, em seguida, uma operação Lerp simples entre duas cores usando RGB seria:

public static Color Lerp(this Color colour, Color to, float amount)
{
    // start colours as lerp-able floats
    float sr = colour.R, sg = colour.G, sb = colour.B;

    // end colours as lerp-able floats
    float er = to.R, eg = to.G, eb = to.B;

    // lerp the colours to get the difference
    byte r = (byte) sr.Lerp(er, amount),
         g = (byte) sg.Lerp(eg, amount),
         b = (byte) sb.Lerp(eb, amount);

    // return the new colour
    return Color.FromArgb(r, g, b);
}

Um exemplo da aplicação do presente seria algo como:

// make red 50% lighter:
Color.Red.Lerp( Color.White, 0.5f );

// make red 75% darker:
Color.Red.Lerp( Color.Black, 0.75f );

// make white 10% bluer:
Color.White.Lerp( Color.Blue, 0.1f );

HSV (Hue / Saturation / Value) também chamado de HSL (Hue / Saturation / Lightness) é apenas uma representação de cor diferente.

Com esta representação é mais fácil para ajustar o brilho. Então converso de RGB para HSV, iluminar o 'V', em seguida, converter de volta para RGB.

Abaixo está algum código C para converter

void RGBToHSV(unsigned char cr, unsigned char cg, unsigned char cb,double *ph,double *ps,double *pv)
{
double r,g,b;
double max, min, delta;

/* convert RGB to [0,1] */

r = (double)cr/255.0f;
g = (double)cg/255.0f;
b = (double)cb/255.0f;

max = MAXx(r,(MAXx(g,b)));
min = MINx(r,(MINx(g,b)));

pv[0] = max;

/* Calculate saturation */

if (max != 0.0)
    ps[0] = (max-min)/max;
else
    ps[0] = 0.0; 

if (ps[0] == 0.0)
{
    ph[0] = 0.0f;   //UNDEFINED;
    return;
}
/* chromatic case: Saturation is not 0, so determine hue */
delta = max-min;

if (r==max)
{
    ph[0] = (g-b)/delta;
}
else if (g==max)
{
    ph[0] = 2.0 + (b-r)/delta;
}
else if (b==max)
{
    ph[0] = 4.0 + (r-g)/delta;
}
ph[0] = ph[0] * 60.0;
if (ph[0] < 0.0)
    ph[0] += 360.0;
}

void HSVToRGB(double h,double s,double v,unsigned char *pr,unsigned char *pg,unsigned char *pb)
{
int i;
double f, p, q, t;
double r,g,b;

if( s == 0 )
{
    // achromatic (grey)
    r = g = b = v;
}
else
{
    h /= 60;            // sector 0 to 5
    i = (int)floor( h );
    f = h - i;          // factorial part of h
    p = v * ( 1 - s );
    q = v * ( 1 - s * f );
    t = v * ( 1 - s * ( 1 - f ) );
    switch( i )
    {
    case 0:
        r = v;
        g = t;
        b = p;
    break;
    case 1:
        r = q;
        g = v;
        b = p;
    break;
    case 2:
        r = p;
        g = v;
        b = t;
    break;
    case 3:
        r = p;
        g = q;
        b = v;
    break;
    case 4:
        r = t;
        g = p;
        b = v;
    break;
    default:        // case 5:
        r = v;
        g = p;
        b = q;
    break;
    }
}
r*=255;
g*=255;
b*=255;

pr[0]=(unsigned char)r;
pg[0]=(unsigned char)g;
pb[0]=(unsigned char)b;
}

rico Newman discute cor HSL com relação ao .NET System.Drawing.Color em seu blog e até mesmo fornece uma classe HSLColor que faz todo o trabalho para você. Converter seu System.Drawing.Color a um HSLColor, adicione / subtraem valores contra a Luminosidade, e converter de volta para System.Drawing.Color para uso em sua aplicação.

Você pode converter sua cor no HSL cor-espaço, manipulá-lo lá e converter de volta a sua cor-espaço de escolha (o mais provável é RGB)

Cores mais claras têm uma L-valor mais alto, mais escura a mais baixa.

Aqui está o material relevante e todas as equações:

http://en.wikipedia.org/wiki/HSL_color_space

Outro método é simplesmente interpolar sua cor com branco ou preto. Isso também irá desaturate a cor um pouco, mas é mais barato para calcular.

Eu tenho usado o ControlPaint.Dark () e .Light () in System.Windows.Forms.

Eu estou supondo que você está usando RGB com valores de byte (0 a 255) já que é muito comum em todos os lugares.

Para mais brilhante, a média dos valores RGB com o RGB de branco. Ou, para ter algum controle sobre a quantidade de brilho, misture-os em alguma proporção. Vamos f variam de 0.0 a 1.0, então:

Rnew = (1-f)*R + f*255
Gnew = (1-f)*G + f*255
Bnew = (1-f)*B + f*255

Para mais escuro, use o RGB de preto -. Que, sendo todos os zeros, torna a matemática mais fácil

Eu deixar de fora detalhes tais como a conversão de parte de trás resultado em bytes, o que provavelmente você gostaria de fazer.

Se você estiver usando cores RGB gostaria de transformar este paramaters cores para HSL (matiz, saturação, luminosidade), modifique o parâmetro leveza e, em seguida, transformar de volta para RGB. Google ao redor e você vai encontrar um monte de exemplos de código sobre como fazer essas transformações representação de cores (RGB para HSL e vice-versa).

Este é o que eu encontrei rapidamente: http://bytes.com/forum/thread250450.html

Assumindo que você obter a cor como RGB, primeiro convertê-lo para HSV (matiz, saturação, valor) de espaço de cores. Em seguida, aumentar / diminuir o valor para produzir tom mais claro / escuro da cor. Em seguida, converter de volta para RGB.

Se suas cores estão no formato RGB (ou, presumivelmente CMYK), você pode usar o método bastante bruto de aumentar o valor de cada componente da cor. Por exemplo, em cores HTML são representados como três números hexadecimais de dois dígitos. # ff0000 lhe dará um vermelho brilhante, que pode então ser desbotada, aumentando os valores do G e componenets B na mesma quantidade, como # ff5555 (dá um vermelho mais claro). Presumivelmente para matiz, saturação e luminosidade (HSL) cores, você pode simplesmente levantar o componente L, mas não posso dizer com certeza; Estou menos familiarizados com o espaço de cor.

Como eu disse, no entanto, este método é bastante bruto. Das minhas memórias de Live Messenger, parece que você está tentando fazer gradientes, que podem ser aplicados realmente muito facilmente em Windows Presentation Foundation (WPF, parte do .NET 3.0). WPF suporta muitos tipos diferentes de escova gradiente, incluindo gradientes lineares e radiais.

Posso altamente recomendo o livro de Adam Nathan Windows Presentation Foundation desencadeada como um bom e introdução completa ao WPF.

HTH

As variações de cores são melhor feito no HSL / HSV.

Um bom teste é para interpolar entre dois valores equivalentes no espaço RGB e espaço HSL. A rampa no espaço HSL parece uma progressão natural. No espaço RGB que normalmente parece bastante natural. HSL mapeia para a nossa percepção do espaço de cor visual muito melhor do que RGB.

A idéia de converter para HSV ou algum outro espaço de cor parece bom, e pode ser necessário para o trabalho de cores precisa, mas para fins comuns o erro de trabalhar em RGB pode não ser suficiente para a matéria. Além disso, ele pode ser uma dor para lidar com casos de fronteira: RGB é um espaço em forma de cubo, enquanto HSV não é. Se trabalhar com valores de bytes, você pode ter muitos-para-um e um-para-muitos mapeamentos entre os espaços. Isto pode ou não pode ser um problema, dependendo da aplicação. YMMV

notas Este href="http://www.csharp411.com/lighten-and-darken-colors-in-net/" rel="nofollow site que você pode usar o classe ControlPaint dentro da BCL C # System.Windows.Forms namespace.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top