Come trovare un bel colore del carattere se il colore di sfondo è noto? [chiuso]


86

Sembra che ci siano così tante app web per ruote dei colori, selettori di colori e abbinamenti di colori là fuori, dove dai un colore e loro troveranno un paio di altri colori che creeranno un layout armonico quando vengono usati in combinazione. Tuttavia, la maggior parte di essi si concentra solo sui colori di sfondo e qualsiasi testo stampato su ciascun colore di sfondo (se il testo viene stampato nell'anteprima) è bianco o nero.

Il mio problema è diverso. Conosco il colore di sfondo che desidero utilizzare per un'area di testo. Ciò di cui ho bisogno è scegliere un paio di colori (più sono, meglio è) che posso usare come colori dei caratteri su questo sfondo. La cosa più importante è che il colore assicurerà che il carattere sia leggibile (il contrasto non è troppo basso, forse anche non troppo alto per evitare che gli occhi siano stressati) e, naturalmente, che la combinazione di primo piano e sfondo sia semplicemente buona.

Qualcuno è a conoscenza di una simile applicazione? Preferirei un'applicazione web a tutto ciò che devo scaricare. Grazie.

Risposte:


39

Se hai bisogno di un algoritmo, prova questo: Converti il ​​colore dallo spazio RGB allo spazio HSV (tonalità, saturazione, valore). Se il tuo framework UI non è in grado di farlo, controlla questo articolo: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

La tonalità è in [0,360). Per trovare il colore "opposto" (pensa a colorwheel), aggiungi semplicemente 180 gradi:

h = (h + 180) % 360;

Per saturazione e valore, invertirli:

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

Converti di nuovo in RGB. Questo dovrebbe sempre darti un contrasto elevato anche se la maggior parte delle combinazioni apparirà brutta.

Se vuoi evitare la parte "brutta", costruisci una tabella con diverse combinazioni "buone", trova quella con la differenza minore

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 usalo.


4

Ok, questa non è ancora la migliore soluzione possibile, ma un buon punto di partenza. Ho scritto una piccola app Java che calcola il rapporto di contrasto di due colori ed elabora solo i colori con un rapporto di 5: 1 o migliore - questo rapporto e la formula che uso sono stati rilasciati dal W3C e probabilmente sostituiranno l'attuale raccomandazione (che Considero molto limitato). Crea un file nella directory di lavoro corrente denominato "selected-font-colors.html", con il colore di sfondo scelto e una riga di testo in ogni colore che ha superato questo test W3C. Si aspetta un singolo argomento, essendo il colore di sfondo.

Ad esempio, puoi chiamarlo così

java FontColorChooser 33FFB4

quindi apri il file HTML generato in un browser a tua scelta e scegli un colore dall'elenco. Tutti i colori forniti hanno superato il test W3C per questo colore di sfondo. Puoi modificare il taglio sostituendo 5 con un numero a tua scelta (i numeri più bassi consentono contrasti più deboli, ad esempio 3 si assicurerà solo che il contrasto sia 3: 1, 10 si assicurerà che sia almeno 10: 1) e puoi anche tagliare per evitare contrasti troppo alti (assicurandosi che sia inferiore a un certo numero), ad esempio aggiungendo

|| cDiff > 18.0

alla clausola if farà in modo che il contrasto non sia troppo estremo, poiché contrasti troppo estremi possono stressare i tuoi occhi. Ecco il codice e divertiti a giocarci un po ':-)

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

Più uno, il calcolo del contrasto, esattamente quello che stavo cercando.
Max Kielland

2

Questa è una domanda interessante, ma non credo che sia effettivamente possibile. Il fatto che due colori "si adattino" o meno come colori di sfondo e di primo piano dipende dalla tecnologia di visualizzazione e dalle caratteristiche fisiologiche della visione umana, ma soprattutto dai gusti personali plasmati dall'esperienza. Una rapida occhiata a MySpace mostra abbastanza chiaramente che non tutti gli esseri umani percepiscono i colori allo stesso modo. Non penso che questo sia un problema che può essere risolto algoritmicamente, sebbene possa esserci un enorme database da qualche parte con colori di corrispondenza accettabili.


2

Ho implementato qualcosa di simile per un motivo diverso: era il codice per dire all'utente finale se i colori di primo piano e di sfondo selezionati avrebbero prodotto testo illeggibile. Per fare ciò, invece di esaminare i valori RGB, ho convertito il valore del colore in HSL / HSV e poi ho determinato sperimentalmente quale fosse il mio punto di cutoff per la leggibilità confrontando i valori fg e bg. Questo è qualcosa che potresti voler / dover considerare.


2

In una recente applicazione che ho realizzato, ho usato i colori invertiti. Con i valori r, ge b in mano, calcola (in questo esempio, la gamma dei colori varia da 0 a 255):

r = 127-(r-127) and so on.

1

Potrebbe essere strano rispondere alla mia stessa domanda, ma ecco un altro selettore di colori davvero interessante che non ho mai visto prima. Non risolve neanche il mio problema: - ((((tuttavia penso che sia molto più interessante per questi che conosco già.

http://www.colorjack.com/

A destra, sotto Strumenti, seleziona "Sfera di colore", una sfera molto potente e personalizzabile (guarda cosa puoi fare con i popup in alto), "Galassia di colore", non sono ancora sicuro di come funzioni, ma sembra bello e anche "Color Studio" è carino. Inoltre può esportare in tutti i tipi di formati (ad esempio Illustrator o Photoshop, ecc.)

Che ne dici di questo, scelgo il mio colore di sfondo lì, lascio che crei un colore complementare (dal primo pop-up) - questo dovrebbe avere il più alto contrasto e quindi essere meglio leggibile, ora seleziona il colore complementare come colore principale e seleziona neutro? Hmmm ... neanche un granché, ma stiamo migliorando ;-)


Nah, non è affatto strano rispondere alla tua stessa domanda, ho finito per farlo un paio di volte io stesso e ottenere le risposte là fuori migliora solo la comunità.
Dillie-O

0

Hai pensato di lasciare che l'utente della tua applicazione selezioni la propria combinazione di colori? Sicuramente non sarai in grado di accontentare tutti i tuoi utenti con la tua selezione, ma puoi consentire loro di trovare ciò che piace loro.


1
Non c'è niente di sbagliato nel lasciare che l'utente decida, ma dovrei comunque includere almeno un utile tema di colori predefinito, no? Non può essere che sia illeggibile e brutto da morire di default fino a quando ogni utente non lo risolve ;-)
Mecki

0

Simile al suggerimento di @Aaron Digulla, tranne per il fatto che suggerirei uno strumento di progettazione grafica, selezionare il colore di base, nel tuo caso il colore di sfondo, quindi regolare Tonalità, Saturazione e Valore. Usandolo puoi creare campioni di colore molto facilmente. Paint.Net è gratuito e lo uso sempre per questo e anche gli strumenti a pagamento lo faranno.


0

Personalmente non credo che possiamo trovare un algoritmo per calcolare il colore del testo più abbinato specificando il colore di sfondo.

Penso che attualmente l'artista dovrebbe avere un elenco di coppie di colori che ha una buona qualità di lettura, possiamo aggiungerle a una tabella e impostare una di queste coppie in modo casuale come tema di lettura ...

questo è molto ragionevole e non avremo brutte coppie di colori ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.