辅助功能 - 如果知道背景颜色,如何找到漂亮的字体颜色?

似乎有很多色轮,颜色选择器和颜色匹配器网络应用程序在那里,你给出一种颜色,他们会发现一些其他颜色,当组合使用时将创建谐波布局。 但是,它们中的大多数仅关注背景颜色,并且在每种背景颜色上打印的任何文本(如果在预览中完全打印文本)是黑色或白色。

我的问题不同了。 我知道我想用于文本区域的背景颜色。 我需要帮助的是选择几种颜色(更多,更好,我可以在这个背景上用作字体颜色)。 最重要的是,颜色将确保字体是可读的(对比度不是太低,也可能不是太高,以避免眼睛受到压力),当然,前景和背景的组合看起来很好。

有人知道这样的申请吗? 我更喜欢Web应用程序,我需要下载任何内容。 谢谢。

Mecki asked 2019-09-12T22:38:09Z
9个解决方案
39 votes

如果您需要算法,请尝试以下操作:将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))

并使用它。

Aaron Digulla answered 2019-09-12T22:38:54Z
4 votes

好吧,这仍然不是最好的解决方案,但是一个很好的开始。 我写了一个小Java应用程序,计算两种颜色的对比度,只处理比例为5:1或更好的颜色 - 这个比例和我使用的公式已经由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);
    }
}
Mecki answered 2019-09-12T22:39:40Z
2 votes

这是一个有趣的问题,但我不认为这实际上是可行的。 两种颜色“适合”作为背景和前景色是否取决于人类视觉的显示技术和生理特征,但最重要的是取决于经验所塑造的个人品味。 快速浏览MySpace非常清楚地表明并非所有人都以同样的方式感知颜色。 我不认为这是一个可以通过算法解决的问题,尽管可能存在一个可接受的匹配颜色的巨大数据库。

MusiGenesis answered 2019-09-12T22:40:05Z
2 votes

我已经实现了类似的不同原因 - 这是代码告诉最终用户他们选择的前景和背景颜色是否会导致不可读的文本。 为了做到这一点,我没有检查RGB值,而是将颜色值转换为HSL / HSV,然后通过实验确定我的截止点在比较fg和bg值时的可读性。 这是您可能需要/需要考虑的事情。

RedFilter answered 2019-09-12T22:40:30Z
2 votes

在我最近的一个应用程序中,我使用了倒置颜色。 使用r,g和b值,只需计算(在此示例中,颜色范围从0到255):

r = 127-(r-127) and so on.
Flávio Batista answered 2019-09-12T22:40:53Z
1 votes

回答我自己的问题可能很奇怪,但这是另一个我以前从未见过的非常酷的颜色选择器。 它也没有解决我的问题: - (((但是我认为这些我已经知道它们要凉爽得多。

[http://www.colorjack.com/]

在右侧,在工具下选择“Color Sphere”,一个非常强大且可自定义的球体(看看你可以用弹出窗口做什么),“Color Galaxy”,我仍然不确定它是如何工作的,但看起来 酷和“彩色工作室”也很好。 此外,它可以导出到所有类型的格式(例如Illustrator或Photoshop等)

怎么样,我选择我的背景颜色,让它创建一个免费的颜色(从第一个弹出窗口) - 这应该具有最高的对比度,因此最好的可读性,现在选择补色作为主色并选择中性? 嗯...也不太好,但我们越来越好;-)

Mecki answered 2019-09-12T22:41:37Z
0 votes

您是否考虑让应用程序的用户选择自己的配色方案? 如果没有失败,您将无法满足所有用户的选择,但您可以让他们找到喜欢的用户。

billcoke answered 2019-09-12T22:42:01Z
0 votes

类似于@Aaron Digulla的建议,除了我建议使用图形设计工具,选择基色,在您的情况下选择背景颜色,然后调整色调,饱和度和值。 使用它,您可以非常轻松地创建颜色样本。 Paint.Net是免费的,我一直都在使用它,而且付费工具也会这样做。

MotoWilliams answered 2019-09-12T22:42:24Z
0 votes

就个人而言,我认为我们不能找到一种算法来通过指定背景颜色来计算最匹配的文本颜色。

我认为目前艺术家应该有一个具有良好阅读质量的颜色对列表,我们可以将它们添加到一个表格中,并随机设置其中一对作为我们的阅读主题......

这是非常合理的,我们不会得到丑陋的颜色对....

flypig answered 2019-09-12T22:43:01Z
translate from https://stackoverflow.com:/questions/301869/how-to-find-good-looking-font-color-if-background-color-is-known