Comment trouver une bonne couleur de police si la couleur d'arrière-plan est connue? [fermé]

86

Il semble y avoir tellement d'applications Web de roue chromatique, de sélecteur de couleurs et de correspondance de couleurs, où vous donnez une couleur et où ils trouveront quelques autres couleurs qui créeront une disposition harmonique lorsqu'ils seront utilisés en combinaison. Cependant, la plupart d'entre eux se concentrent uniquement sur les couleurs d'arrière-plan et tout texte imprimé sur chaque couleur d'arrière-plan (si le texte est imprimé dans l'aperçu) est soit noir, soit blanc.

Mon problème est différent. Je connais la couleur d'arrière-plan que je souhaite utiliser pour une zone de texte. Ce dont j'ai besoin d'aide, c'est de choisir quelques couleurs (plus il y en a, plus c'est de fous) que je peux utiliser comme couleurs de police sur cet arrière-plan. Le plus important est que la couleur garantira que la police est lisible (le contraste n'est pas trop faible, peut-être aussi ne pas être trop élevé pour éviter que les yeux ne soient stressés) et bien sûr que la combinaison du premier plan et de l'arrière-plan semble juste bonne.

Quelqu'un est-il au courant d'une telle application? Je préfère une application Web à tout ce que je dois télécharger. Merci.

Mecki
la source

Réponses:

39

Si vous avez besoin d'un algorithme, essayez ceci: Convertissez la couleur de l'espace RVB en espace HSV (Teinte, Saturation, Valeur). Si votre infrastructure d'interface utilisateur ne peut pas le faire, consultez cet article: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

La teinte est en [0,360). Pour trouver la couleur "opposée" (pensez à la roue chromatique), ajoutez simplement 180 degrés:

h = (h + 180) % 360;

Pour la saturation et la valeur, inversez-les:

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

Reconvertissez en RVB. Cela devrait toujours vous donner un contraste élevé même si la plupart des combinaisons auront l'air moche.

Si vous voulez éviter la partie "moche", construisez une table avec plusieurs "bonnes" combinaisons, trouvez celle avec le moins de différence

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

et utilisez ça.

Aaron Digulla
la source
4

D'accord, ce n'est toujours pas la meilleure solution possible, mais un bon point de départ. J'ai écrit une petite application Java qui calcule le rapport de contraste de deux couleurs et ne traite que les couleurs avec un rapport de 5: 1 ou mieux - ce rapport et la formule que j'utilise ont été publiés par le W3C et remplaceront probablement la recommandation actuelle (qui Je considère très limité). Il crée un fichier dans le répertoire de travail actuel nommé "selected-font-colors.html", avec la couleur d'arrière-plan de votre choix et une ligne de texte dans chaque couleur qui a réussi ce test W3C. Il attend un seul argument, étant la couleur d'arrière-plan.

Par exemple, vous pouvez l'appeler comme ça

java FontColorChooser 33FFB4

puis ouvrez simplement le fichier HTML généré dans un navigateur de votre choix et choisissez une couleur dans la liste. Toutes les couleurs données ont réussi le test W3C pour cette couleur d'arrière-plan. Vous pouvez changer la coupure en remplaçant 5 par un nombre de votre choix (les nombres inférieurs permettent des contrastes plus faibles, par exemple 3 s'assurera que le contraste est 3: 1, 10 s'assurera qu'il est au moins 10: 1) et vous pouvez également couper pour éviter des contrastes trop élevés (en s'assurant qu'il est inférieur à un certain nombre), par exemple en ajoutant

|| cDiff > 18.0

à la clause if garantira que le contraste ne sera pas trop extrême, car des contrastes trop extrêmes peuvent stresser vos yeux. Voici le code et amusez-vous un peu à jouer avec :-)

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
la source
De plus, le calcul du contraste, exactement ce que je recherchais.
Max Kielland
2

C'est une question intéressante, mais je ne pense pas que ce soit réellement possible. Le fait que deux couleurs correspondent ou non comme couleurs d'arrière-plan et de premier plan dépend de la technologie d'affichage et des caractéristiques physiologiques de la vision humaine, mais surtout des goûts personnels façonnés par l'expérience. Un rapide passage sur MySpace montre assez clairement que tous les êtres humains ne perçoivent pas les couleurs de la même manière. Je ne pense pas que ce soit un problème qui puisse être résolu par un algorithme, bien qu'il puisse y avoir une énorme base de données quelque part de couleurs de correspondance acceptables.

MusiGenesis
la source
2

J'ai implémenté quelque chose de similaire pour une raison différente - c'était du code pour dire à l'utilisateur final si les couleurs de premier plan et d'arrière-plan qu'ils ont sélectionnées entraîneraient un texte illisible. Pour ce faire, plutôt que d'examiner les valeurs RVB, j'ai converti la valeur de couleur en HSL / HSV, puis j'ai déterminé par expérimentation quel était mon point de coupure pour la lisibilité lors de la comparaison des valeurs fg et bg. C'est quelque chose que vous voudrez peut-être / devez considérer.

RedFilter
la source
2

Dans une application récente que j'ai faite, j'ai utilisé les couleurs inversées. Avec les valeurs r, g et b en main, calculez simplement (dans cet exemple, la gamme de couleurs varie de 0 à 255):

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

Cela peut être étrange de répondre à ma propre question, mais voici un autre sélecteur de couleurs vraiment cool que je n'avais jamais vu auparavant. Cela ne résout pas non plus mon problème: - (((((mais je pense que c'est beaucoup plus cool pour ceux que je connais déjà.

http://www.colorjack.com/

Sur la droite, sous Outils, sélectionnez "Color Sphere", une sphère très puissante et personnalisable (voyez ce que vous pouvez faire avec les pop-ups en haut), "Color Galaxy", je ne sais toujours pas comment cela fonctionne, mais ressemble cool et "Color Studio" est également agréable. De plus, il peut exporter vers tous les types de formats (par exemple Illustrator ou Photoshop, etc.)

Que diriez-vous de cela, je choisis ma couleur d'arrière-plan là-bas, je la laisse créer une couleur complémentaire (à partir de la première fenêtre contextuelle) - cela devrait avoir le contraste le plus élevé et donc être mieux lisible, maintenant sélectionnez la couleur complémentaire comme couleur principale et sélectionnez neutre? Hmmm ... pas trop bien non plus, mais on va mieux ;-)

Mecki
la source
Non, ce n'est pas du tout étrange de répondre à votre propre question, j'ai fini par le faire plusieurs fois moi-même et obtenir les réponses ne fait que parier la communauté.
Dillie-O
0

Avez-vous envisagé de laisser l'utilisateur de votre application sélectionner son propre jeu de couleurs? Sans faute, vous ne pourrez pas plaire à tous vos utilisateurs avec votre sélection mais vous pouvez leur permettre de trouver ce qui leur plaît.

billcoke
la source
1
Il n'y a rien de mal à laisser l'utilisateur décider, mais je devrais au moins inclure un thème de couleur par défaut utile, n'est-ce pas? Cela ne peut pas être qu'il soit illisible et moche comme l'enfer par défaut jusqu'à ce que chaque utilisateur le corrige ;-)
Mecki
0

Similaire à la suggestion de @Aaron Digulla, sauf que je suggérerais un outil de conception graphique, sélectionnez la couleur de base, dans votre cas la couleur d'arrière-plan, puis ajustez la teinte, la saturation et la valeur. Grâce à cela, vous pouvez créer des échantillons de couleurs très facilement. Paint.Net est gratuit et je l'utilise tout le temps pour cela et les outils payants le feront également.

MotoWilliams
la source
0

Personnellement, je ne pense pas que nous puissions trouver un algorithme pour calculer la couleur de texte la plus adaptée en spécifiant la couleur d'arrière-plan.

Je pense qu'actuellement, l'artiste devrait avoir une liste de paires de couleurs qui a une bonne qualité de lecture, nous pouvons les ajouter à un tableau, et définir l'une de ces paires au hasard comme thème de lecture ...

c'est beaucoup plus raisonnable et nous n'obtiendrons pas de paires de couleurs laides ....

flypig
la source