Programaticamente escolher cores com alto contraste
Pergunta
Esta deve ser uma pergunta simples, mas eu não tenho sido capaz de encontrar uma maneira de fazê-lo funcionar.
Essencialmente, eu tenho uma página localhost bobo que eu uso no meu webdevelopment. Quando estou navegando entre o nosso servidor de desenvolvimento e minha versão local do código C # (redirecionado a partir da url dev via arquivo host) eu tenho sido conhecida a esquecer o que dev.foo.com "às vezes pontos na -. Local ou servidor
Então, eu criei uma página que irá executar localmente como página padrão da minha página web padrão, para que eu possa facilmente identificar o meu localhost do servidor.
Esta página faz um monte de coisas aleatoriamente (incluindo a geração de estatísticas a partir de um personagem para D & D), incluindo a definição de uma cor de fundo aleatória. Eu faço isso através da geração de 3 números aleatórios entre 0 e 255, e definindo-as como o valor RGB para a cor de fundo do corpo em CSS.
Dada a 3 ints R, G e B, como determinar R2, G2, B2 e de tal modo que a segunda cor terão de alto contraste com a primeira? Eu gosto de ter a página ter cores de fundo aleatório (que me impede de me acostumando com o visual da página de destino), mas eu também gosto de ser capaz de ler o texto.
Solução
Você precisa de uma diferença de brilho para o texto a ser lido, como a própria visão de cores tem muito baixa resolução.
Assim como um algoritmo eu sugiro o seguinte:
-
Escolha uma cor de fundo aleatória.
-
Em seguida, decidir se é um de uma cor clara ou escura. Por exemplo, você pode verificar se a média das três cores primárias é maior ou igual 128.
-
Para um texto preto uso cor clara, por uma escura texto branco.
Outras dicas
"Contraste" é uma palavra carregada. Se você só se preocupam com a possibilidade de ler o texto, em seguida, uma maneira fácil é trabalhar em um espaço de cor à base de luminância como HSL, e escolher primeiro plano e cores de fundo com grandes diferenças de luminância.
A conversão entre HSL e RGB é bem conhecido -. Ver Wikipedia para os detalhes
Se você está falando de contraste de cor real, não é tão cut-and-dried (há uma série de fatores perceptivos que, tanto quanto eu sei, não foram reduzidos a um espaço de cores individuais), mas eu suspeito que você não precisa que o nível de sofisticação.
Confira esta solução PHP: Calculando contraste da cor com PHP por Andreas Gohr. Ele pode ser portado para qualquer idioma, é claro.
Ele também tem uma ótima demonstração de seu analisador de contraste onde você pode encontrar alguns níveis de contraste mínima para trabalhar.
Você pode usar o método GetBrightness()
na classe Color
. Ele retorna um valor float de 0,0 (brilho de preto) para 1,0 (branco).
Uma solução simples seria:
var color1 = new Color.FromArgb(r1, g1, b1);
var brightness = color1.GetBrightness();
var color2 = brightness > 0.5 ? Color.Black : Color.White;
Eu fiz algo parecido com isso em um aplicativo Palm OS. Isto é o que eu vim acima com. Ele não lhe dá cores "alto contraste" mas dá-lhe uma cor de fundo que é bastante diferente da cor do texto a ser bastante legível:
// Black background is a special case. It's fairly likely to occur and
// the default color shift we do isn't very noticeable with very dark colors.
if (backColor.r < 0x20 && backColor.g < 0x20 && backColor.b < 0x20)
{
textColor.r = backColor.r + 0x20;
textColor.g = backColor.g + 0x20;
textColor.b = backColor.b + 0x20;
}
else
{
textColor.r = backColor.r + ((backColor.r < 128) ? 0x10 : -0x10);
textColor.g = backColor.g + ((backColor.g < 128) ? 0x10 : -0x10);
textColor.b = backColor.b + ((backColor.b < 128) ? 0x10 : -0x10);
}
Você não pode precisar fazer negro como um caso especial para seus propósitos -. Manipulação de cor da Palm é um pouco descolados (cor de 16 bits)
Há alguns bons recursos (e algoritmos) para abordar esta em http://juicystudio.com/ artigo / luminositycontrastratioalgorithm.php
Estas respostas são mais ou menos o que sugere usar uma das duas ou três opções de cores com base em se a cor é clara ou escura.
Eu uso uma abordagem um pouco diferente e funcionou elegantemente no meu caso. Aqui é a implementação.
int color = your_color;
contrastColor = Color.rgb(255-(color >> 16)&0xFF, 255-(color >> 8)&0xFF, 255- color&0xFF);
simples É de e maravilhoso.
Se você virar todos os bits, você terá a cor "oposto", que seria muito bom contraste.
Eu acredito que é o operador ~ em C #:
R2 = ~R1;
G2 = ~G1;
B2 = ~B1;
Para melhor uso contraste este código
function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){
$L1 = 0.2126 * pow($R1/255, 2.2) +
0.7152 * pow($G1/255, 2.2) +
0.0722 * pow($B1/255, 2.2);
$L2 = 0.2126 * pow($R2/255, 2.2) +
0.7152 * pow($G2/255, 2.2) +
0.0722 * pow($B2/255, 2.2);
if($L1 > $L2){
return ($L1+0.05) / ($L2+0.05);
}else{
return ($L2+0.05) / ($L1+0.05);
}
}
function get_the_contrast($c1, $c2) {
return (lumdiff(hexdec(substr($c1,0,2)),
hexdec(substr($c1,2,2)),hexdec(substr($c1,4,2)),
hexdec(substr($c2,0,2)),hexdec(substr($c2,2,2)),
hexdec(substr($c2,4,2))));
}
O método acima (AVG (vermelho, verde, azul)> 128) não é realmente bom.
private Color GetContrastingColor(Color color)
{
int r = color.R > 0 ? 256 - color.R : 255;
int g = color.G > 0 ? 256 - color.G : 255;
int b = color.B > 0 ? 256 - color.B : 255;
return System.Drawing.Color.FromArgb(r, g, b);
}
Graças ao @starblue !
Aqui está o código C#
que eu uso
public static string GetContrastBlackOrWhiteColorAsHtmlColorCode(Color c)
{
System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml("transparent");
try
{
if (c.R >= 128 && c.G >= 128 && c.B >= 128)
{
return System.Drawing.ColorTranslator.ToHtml(Color.Black);
}
else
{
return System.Drawing.ColorTranslator.ToHtml(Color.White);
}
}
catch (Exception)
{
}
return System.Drawing.ColorTranslator.ToHtml(color);
}