Como encontrar uma cor de fonte bonita se a cor de fundo for conhecida? [fechadas]

86

Parece haver muitos aplicativos da web de roda de cores, seletor de cores e combinação de cores por aí, onde você dá uma cor e eles vão encontrar algumas outras cores que criarão um layout harmônico quando usadas em combinação. No entanto, a maioria deles enfoca apenas cores de fundo e qualquer texto impresso em cada cor de fundo (se o texto for impresso na visualização) é preto ou branco.

Meu problema é diferente. Eu sei a cor de fundo que desejo usar para uma área de texto. Preciso de ajuda para escolher algumas cores (quanto mais, melhor) que posso usar como cores de fonte neste fundo. O mais importante é que a cor garantirá que a fonte seja legível (contraste não sendo muito baixo, também talvez não seja muito alto para evitar que os olhos sejam forçados) e, claro, que a combinação de primeiro e segundo plano parece boa.

Alguém está ciente de tal aplicativo? Eu prefiro um aplicativo da web a qualquer coisa que eu tenha que baixar. Obrigado.

Mecki
fonte

Respostas:

39

Se você precisar de um algoritmo, tente o seguinte: Converta a cor do espaço RGB em espaço HSV (matiz, saturação, valor). Se a sua estrutura de IU não puder fazer isso, verifique este artigo: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

O matiz está em [0,360). Para encontrar a cor "oposta" (pense na roda de cores), basta adicionar 180 graus:

h = (h + 180) % 360;

Para saturação e valor, inverta-os:

l = 1.0 - l;
v = 1.0 - v;

Converta de volta para RGB. Isso sempre deve fornecer um alto contraste, embora a maioria das combinações pareça feia.

Se você quiser evitar a parte "feia", construa uma mesa com várias combinações "boas", encontre aquela com a menor diferença

def q(x):
    return x*x
def diff(col1, col2):
    return math.sqrt(q(col1.r-col2.r) + q(col1.g-col2.g) + q(col1.b-col2.b))

e usar isso.

Aaron Digulla
fonte
4

Ok, ainda não é a melhor solução possível, mas é um bom ponto de partida. Eu escrevi um pequeno aplicativo Java que calcula a proporção de contraste de duas cores e só processa cores com uma proporção de 5: 1 ou melhor - esta proporção e a fórmula que uso foram lançadas pelo W3C e provavelmente irão substituir a recomendação atual (que Considero muito limitado). Ele cria um arquivo no diretório de trabalho atual denominado "choice-font-colors.html", com a cor de fundo de sua escolha e uma linha de texto em todas as cores que passaram neste teste W3C. Ele espera um único argumento, sendo a cor de fundo.

Por exemplo, você pode chamá-lo assim

java FontColorChooser 33FFB4

em seguida, basta abrir o arquivo HTML gerado em um navegador de sua escolha e escolher uma cor da lista. Todas as cores fornecidas passaram no teste W3C para esta cor de fundo. Você pode alterar o corte substituindo 5 por um número de sua escolha (números menores permitem contrastes mais fracos, por exemplo, 3 garantirá que o contraste seja 3: 1, 10 garantirá que seja pelo menos 10: 1) e você também pode corte para evitar contrastes muito altos (certificando-se de que é menor que um certo número), por exemplo, adicionando

|| cDiff > 18.0

à cláusula if garantirá que o contraste não seja muito extremo, pois contrastes muito extremos podem estressar seus olhos. Aqui está o código e divirta-se brincando com ele :-)

import java.io.*;

/* For text being readable, it must have a good contrast difference. Why?
 * Your eye has receptors for brightness and receptors for each of the colors
 * red, green and blue. However, it has much more receptors for brightness
 * than for color. If you only change the color, but both colors have the
 * same contrast, your eye must distinguish fore- and background by the
 * color only and this stresses the brain a lot over the time, because it
 * can only use the very small amount of signals it gets from the color
 * receptors, since the breightness receptors won't note a difference.
 * Actually contrast is so much more important than color that you don't
 * have to change the color at all. E.g. light red on dark red reads nicely
 * even though both are the same color, red.
 */


public class FontColorChooser {
    int bred;
    int bgreen;
    int bblue;

    public FontColorChooser(String hexColor) throws NumberFormatException {
        int i;

        i = Integer.parseInt(hexColor, 16);
        bred = (i >> 16);
        bgreen = (i >> 8) & 0xFF;
        bblue = i & 0xFF;
    }

    public static void main(String[] args) {
        FontColorChooser fcc;

        if (args.length == 0) {
            System.out.println("Missing argument!");
            System.out.println(
                "The first argument must be the background" +
                "color in hex notation."
            );
            System.out.println(
                "E.g. \"FFFFFF\" for white or \"000000\" for black."
            );
            return;
        }
        try {
            fcc = new FontColorChooser(args[0]);
        } catch (Exception e) {
            System.out.println(
                args[0] + " is no valid hex color!"
            );
            return;
        }
        try {
            fcc.start();
        } catch (IOException e) {
            System.out.println("Failed to write output file!");
        }
    }

    public void start() throws IOException {
        int r;
        int b;
        int g;
        OutputStreamWriter out;

        out = new OutputStreamWriter(
            new FileOutputStream("chosen-font-colors.html"),
            "UTF-8"
        );

        // simple, not W3C comform (most browsers won't care), HTML header
        out.write("<html><head><title>\n");
        out.write("</title><style type=\"text/css\">\n");
        out.write("body { background-color:#");
        out.write(rgb2hex(bred, bgreen, bblue));
        out.write("; }\n</style></head>\n<body>\n");

        // try 4096 colors
        for (r = 0; r <= 15; r++) {
            for (g = 0; g <= 15; g++) {
                for (b = 0; b <= 15; b++) {
                    int red;
                    int blue;
                    int green;
                    double cDiff;

                    // brightness increasse like this: 00, 11,22, ..., ff
                    red = (r << 4) | r;
                    blue = (b << 4) | b;
                    green = (g << 4) | g;

                    cDiff = contrastDiff(
                        red, green, blue,
                        bred, bgreen, bblue
                    );
                    if (cDiff < 5.0) continue;
                    writeDiv(red, green, blue, out);
                }
            }
        }

        // finalize HTML document
        out.write("</body></html>");

        out.close();
    }

    private void writeDiv(int r, int g, int b, OutputStreamWriter out)
        throws IOException
    {
        String hex;

        hex = rgb2hex(r, g, b);
        out.write("<div style=\"color:#" + hex + "\">");
        out.write("This is a sample text for color " + hex + "</div>\n");
    }

    private double contrastDiff(
        int r1, int g1, int b1, int r2, int g2, int b2
    ) {
        double l1;
        double l2;

        l1 = ( 
            0.2126 * Math.pow((double)r1/255.0, 2.2) +
            0.7152 * Math.pow((double)g1/255.0, 2.2) +
            0.0722 * Math.pow((double)b1/255.0, 2.2) +
            0.05
        );
        l2 = ( 
            0.2126 * Math.pow((double)r2/255.0, 2.2) +
            0.7152 * Math.pow((double)g2/255.0, 2.2) +
            0.0722 * Math.pow((double)b2/255.0, 2.2) +
            0.05
        );

        return (l1 > l2) ? (l1 / l2) : (l2 / l1);
    }

    private String rgb2hex(int r, int g, int b) {
        String rs = Integer.toHexString(r);
        String gs = Integer.toHexString(g);
        String bs = Integer.toHexString(b);
        if (rs.length() == 1) rs = "0" + rs;
        if (gs.length() == 1) gs = "0" + gs;
        if (bs.length() == 1) bs = "0" + bs;
        return (rs + gs + bs);
    }
}
Mecki
fonte
Mais um, cálculo de contraste, exatamente o que eu estava procurando.
Max Kielland
2

Esta é uma pergunta interessante, mas não acho que seja realmente possível. Se duas cores "se encaixam" ou não como cores de fundo e de primeiro plano, depende da tecnologia de exibição e das características fisiológicas da visão humana, mas o mais importante, dos gostos pessoais moldados pela experiência. Uma rápida olhada no MySpace mostra claramente que nem todos os seres humanos percebem as cores da mesma maneira. Não acho que esse seja um problema que possa ser resolvido por algoritmos, embora possa haver um enorme banco de dados em algum lugar de cores correspondentes aceitáveis.

MusiGenesis
fonte
2

Implementei algo semelhante por um motivo diferente - que era um código para informar ao usuário final se as cores de primeiro e segundo plano que eles selecionaram resultariam em texto ilegível. Para fazer isso, em vez de examinar os valores RGB, converti o valor da cor em HSL / HSV e, em seguida, determinei por experimentação qual era o meu ponto de corte para legibilidade ao comparar os valores fg e bg. Isso é algo que você pode querer / precisar considerar.

RedFilter
fonte
2

Em um aplicativo recente que fiz, usei as cores invertidas. Com os valores de r, g e b em mãos, basta calcular (neste exemplo, a faixa de cores varia de 0 a 255):

r = 127-(r-127) and so on.
Flávio Batista
fonte
1

Pode ser estranho responder minha própria pergunta, mas aqui está outro seletor de cores muito legal que eu nunca vi antes. Também não resolve o meu problema: - (((((no entanto acho que é muito mais legal para estes que já conheço).

http://www.colorjack.com/

À direita, em Ferramentas selecione "Color Sphere", uma esfera muito poderosa e personalizável (veja o que você pode fazer com os pop-ups no topo), "Color Galaxy", ainda não tenho certeza de como isso funciona, mas parece legal e "Color Studio" também é bom. Além disso, pode exportar para todos os tipos de formatos (por exemplo, Illustrator ou Photoshop, etc.)

Que tal isso, eu escolho minha cor de fundo lá, deixo criar uma cor complementar (desde o primeiro pop up) - isso deve ter o maior contraste e, portanto, ser mais legível, agora selecione a cor complementar como cor principal e selecione neutro? Hmmm ... não muito bem também, mas estamos melhorando ;-)

Mecki
fonte
Nah, não é nada estranho responder sua própria pergunta, eu acabei fazendo isso algumas vezes e obter as respostas por aí apenas melhora a comunidade.
Dillie-O de
0

Você já pensou em permitir que o usuário do seu aplicativo selecione seu próprio esquema de cores? Sem falta, você não será capaz de agradar a todos os seus usuários com sua seleção, mas pode permitir que eles encontrem o que lhes agrada.

billcoke
fonte
1
Não há nada de errado em deixar o usuário decidir, mas ainda assim devo incluir pelo menos um tema de cores padrão útil, não é? Não pode ser que seja ilegível e feio como o inferno por padrão até que cada usuário o conserte ;-)
Mecki
0

Semelhante à sugestão de @Aaron Digulla, exceto que eu sugeriria uma ferramenta de design gráfico, selecione a cor de base, no seu caso, a cor de fundo, então ajuste o Matiz, Saturação e Valor. Usando isso, você pode criar amostras de cores com muita facilidade. O Paint.Net é grátis e eu o uso o tempo todo para isso e também as ferramentas de pagamento também fazem isso.

MotoWilliams
fonte
0

Pessoalmente, não acho que possamos encontrar um algoritmo para calcular a cor de texto mais correspondente especificando a cor de fundo.

Acho que atualmente o artista deve ter uma lista de pares de cores que tenham boa qualidade de leitura, podemos adicioná-los a uma mesa e definir um desses pares aleatoriamente como nosso tema de leitura ...

isso é muito razoável, e não teremos pares de cores feias ....

porco-espinho
fonte