背景色がわかっている場合、見栄えの良いフォントの色を見つける方法は?[閉まっている]


86

カラーホイール、カラーピッカー、カラーマッチャーのWebアプリは非常にたくさんあるようです。ここでは、1つの色を指定すると、組み合わせて使用​​すると調和のとれたレイアウトを作成する他の色がいくつか見つかります。ただし、それらのほとんどは背景色のみに焦点を当てており、各背景色に印刷されるテキスト(プレビューでテキストが印刷される場合)は黒または白のいずれかです。

私の問題は違います。テキスト領域に使用したい背景色を知っています。私が助けを必要としているのは、この背景のフォントの色として使用できるいくつかの色(より多くの方が楽しい)を選択することです。最も重要なのは、色によってフォントが読みやすくなること(コントラストが低すぎないこと、高すぎて目が強調されないようにすること)、そしてもちろん前景と背景の組み合わせが見栄えがすることです。

そのようなアプリケーションを知っている人はいますか?ダウンロードするものよりもWebアプリケーションの方がいいです。ありがとう。

回答:


39

アルゴリズムが必要な場合は、次のことを試してください。RGB空間からHSV空間(色相、彩度、値)に色を変換します。UIフレームワークでそれができない場合は、次の記事を確認してください:http//en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

色相は[0,360]にあります。「反対の」色(カラーホイールを考えてください)を見つけるには、180度を追加するだけです。

h = (h + 180) % 360;

彩度と値については、それらを反転します。

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

RGBに変換し直します。ほとんどの組み合わせは見苦しく見えますが、これにより常に高いコントラストが得られます。

「醜い」部分を避けたい場合は、いくつかの「良い」組み合わせでテーブルを作成し、違いが最も少ないものを見つけてください

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

そしてそれを使用します。


4

さて、これはまだ最善の解決策ではありませんが、開始するのに良いポイントです。2色のコントラスト比を計算し、5:1以上の比率の色のみを処理する小さなJavaアプリを作成しました。この比率と使用する式は、W3Cによってリリースされており、おそらく現在の推奨事項(私は非常に限られていると思います)。「chosen-font-colors.html」という名前の現在の作業ディレクトリに、選択した背景色と、このW3Cテストに合格したすべての色のテキスト行を含むファイルが作成されます。背景色である単一の引数を期待します。

たとえば、このように呼び出すことができます

java FontColorChooser 33FFB4

次に、生成されたHTMLファイルを任意のブラウザで開き、リストから色を選択します。与えられたすべての色は、この背景色のW3Cテストに合格しました。5を選択した番号に置き換えることでカットオフを変更できます(数値が小さいほどコントラストが弱くなります。たとえば、3はコントラストが3:1であることを確認するだけで、10は少なくとも10:1であることを確認します)。コントラストが高すぎないようにカットオフします(特定の数値よりも小さいことを確認してください)。

|| cDiff > 18.0

if句を使用すると、コントラストが極端になりすぎないようになります。コントラストが極端すぎると、目を強調する可能性があるためです。これがコードで、少し遊んで楽しんでください:-)

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

プラス1、コントラスト計算、まさに私が探していたもの。
Max Kielland 2014

2

これは興味深い質問ですが、実際には不可能だと思います。2色が背景色と前景色に「適合する」かどうかは、ディスプレイテクノロジーと人間の視覚の生理学的特性に依存しますが、最も重要なのは、経験によって形成された個人的な好みに依存します。MySpaceをざっと見てみると、すべての人間が同じように色を認識しているわけではないことがはっきりとわかります。許容できる一致する色のどこかに巨大なデータベースがあるかもしれませんが、これはアルゴリズムで解決できる問題ではないと思います。


2

私は別の理由で同様の何かを実装しました-それはエンドユーザーに彼らが選択した前景色と背景色が読めないテキストをもたらすかどうかを伝えるコードでした。これを行うには、RGB値を調べるのではなく、色の値をHSL / HSVに変換し、fg値とbg値を比較するときに読みやすくするためのカットオフポイントを実験によって決定しました。これはあなたが考慮したい/考慮する必要があるかもしれない何かです。


2

最近作成したアプリケーションでは、反転色を使用しました。r、g、bの値を手元に置いて、計算するだけです(この例では、色の範囲は0から255まで変化します)。

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

1

私自身の質問に答えるのは奇妙かもしれませんが、これは私が今まで見たことがないもう一つの本当にクールなカラーピッカーです。それは私の問題も解決しません:-((((しかし私はすでに知っているこれらよりもはるかにクールだと思います。

http://www.colorjack.com/

右側の[ツール]で、非常に強力でカスタマイズ可能な球体である[カラー球体](上部のポップアップで何ができるかを参照)、[カラーギャラクシー]を選択します。これがどのように機能するかはまだわかりませんが、見た目はかっこいい「ColorStudio」もいいですね。さらに、あらゆる種類の形式(IllustratorやPhotoshopなど)にエクスポートできます。

これはどうですか、そこで背景色を選択し、(最初のポップアップから)補色を作成します-これは最高のコントラストを持ち、したがって最も読みやすいはずです、今度は補色をメインカラーとして選択し、ニュートラルを選択しますか?うーん...あまり大きくはありませんが、私たちは良くなっています;-)


いや、あなた自身の質問に答えるのはまったく不思議ではありません、私はそれを自分で数回やることになりました、そしてそこに答えを得ることはコミュニティをより良くするだけです。
Dillie-O

0

アプリケーションのユーザーに独自の配色を選択させることを検討しましたか?間違いなく、選択したすべてのユーザーを満足させることはできませんが、ユーザーが満足できるものを見つけられるようにすることはできます。


1
ユーザーに決めさせるのは悪いことではありませんが、少なくとも便利なデフォルトのカラーテーマを含める必要がありますね。各ユーザーが修正するまで、デフォルトで読みにくく醜いということはあり得ません;-)
Mecki

0

@Aaron Digullaの提案と似ていますが、グラフィックデザインツールを提案し、基本色(この場合は背景色)を選択してから、色相、彩度、明度を調整します。これを使用すると、色見本を非常に簡単に作成できます。Paint.Netは無料で、私はこれを常に使用しています。また、有料ツールもこれを行います。


0

個人的には、背景色を指定して最も一致するテキストの色を計算するアルゴリズムを見つけることはできないと思います。

現在、アーティストは読書品質の良い色のペアのリストを持っている必要があると思います。それらをテーブルに追加して、これらのペアの1つを読書のテーマとしてランダムに設定できます...

これは非常に合理的であり、醜い色のペアは得られません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.