Как найти красивый цвет шрифта, если известен цвет фона? [закрыто]

86

Кажется, существует так много веб-приложений для цветового круга, выбора цвета и сопоставления цветов, в которых вы указываете один цвет, а они находят пару других цветов, которые при использовании в комбинации создают гармоничный макет. Однако большинство из них фокусируются только на цветах фона, и любой текст, напечатанный на каждом цвете фона (если текст вообще печатается в предварительном просмотре), является либо черным, либо белым.

Моя проблема в другом. Я знаю цвет фона, который хочу использовать для текстовой области. Мне нужна помощь с выбором пары цветов (чем больше, тем веселее), которые я могу использовать в качестве цветов шрифта на этом фоне. Наиболее важно то, что цвет будет обеспечивать читаемость шрифта (контраст не будет слишком низким, а также, возможно, не слишком высоким, чтобы глаза не напрягались) и, конечно же, сочетание переднего плана и фона выглядит хорошо.

Кто-нибудь знает о таком приложении? Я бы предпочел веб-приложение всему, что мне нужно скачать. Спасибо.

Mecki
источник

Ответы:

39

Если вам нужен алгоритм, попробуйте следующее: Преобразуйте цвет из пространства RGB в пространство HSV (оттенок, насыщенность, значение). Если ваша структура пользовательского интерфейса не может этого сделать, ознакомьтесь с этой статьей: 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

Хорошо, это все еще не лучшее решение, но хорошее начало. Я написал небольшое приложение на Java, которое вычисляет коэффициент контрастности двух цветов и обрабатывает цвета только с соотношением 5: 1 или лучше - это соотношение и формула, которую я использую, были выпущены W3C и, вероятно, заменят текущую рекомендацию (которая Считаю очень ограниченным). Он создает файл в текущем рабочем каталоге с именем «selected-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
источник
Плюс один, расчет контрастности, именно то, что я искал.
Макс Килланд
2

Это интересный вопрос, но я не думаю, что это вообще возможно. То, подходят ли два цвета в качестве цветов фона и переднего плана, зависит от технологии отображения и физиологических характеристик человеческого зрения, но, что наиболее важно, от личных вкусов, сформированных опытом. Быстрый просмотр MySpace довольно ясно показывает, что не все люди воспринимают цвета одинаково. Я не думаю, что это проблема, которую можно решить алгоритмически, хотя где-то может быть огромная база данных приемлемых подходящих цветов.

MusiGenesis
источник
2

Я реализовал нечто подобное по другой причине - это был код, который сообщал конечному пользователю, приведет ли выбранный ими цвет переднего плана и фона к нечитаемому тексту. Чтобы сделать это, вместо того, чтобы исследовать значения RGB, я преобразовал значение цвета в HSL / HSV, а затем экспериментально определил, какова была моя точка отсечки для удобочитаемости при сравнении значений fg и bg. Это то, что вы, возможно, захотите / должны принять во внимание.

RedFilter
источник
2

В своем недавнем приложении я использовал инвертированные цвета. Имея в руках значения r, g и b, просто вычислите (в этом примере диапазон цветов варьируется от 0 до 255):

r = 127-(r-127) and so on.
Флавио Батиста
источник
1

Было бы странно ответить на мой собственный вопрос, но вот еще одна действительно классная палитра цветов, которую я никогда раньше не видел. Это тоже не решает мою проблему: - ((((однако я думаю, что это намного круче, чем я уже знаю.

http://www.colorjack.com/

Справа в разделе «Инструменты» выберите «Color Sphere», очень мощную и настраиваемую сферу (посмотрите, что вы можете делать с всплывающими окнами вверху), «Color Galaxy». Я все еще не уверен, как это работает, но выглядит круто и "Color Studio" тоже приятно. Кроме того, он может экспортировать во все форматы (например, Illustrator или Photoshop и т. Д.)

Как насчет этого, я выбираю свой цвет фона там, позволяю ему создать дополнительный цвет (из первого всплывающего окна) - он должен иметь самый высокий контраст и, следовательно, быть лучше читаемым, теперь выберите дополнительный цвет в качестве основного цвета и выберите нейтральный? Хммм ... тоже не очень хорошо, но мы поправляемся ;-)

Mecki
источник
Нет, совсем не странно отвечать на свой вопрос, я сам делал это несколько раз, и получение ответов только улучшает сообщество.
Dillie-O
0

Рассматривали ли вы возможность позволить пользователю вашего приложения выбрать свою собственную цветовую схему? В любом случае вы не сможете порадовать всех своих пользователей своим выбором, но вы можете позволить им найти то, что им нравится.

кокс
источник
1
Нет ничего плохого в том, чтобы позволить пользователю решать, но я все же должен хотя бы включить полезную цветовую тему по умолчанию, не так ли? Не может быть, чтобы он был нечитаемым и чертовски уродливым по умолчанию, пока каждый пользователь не
исправит
0

Подобно предложению @Aaron Digulla, за исключением того, что я бы предложил инструмент графического дизайна, выберите базовый цвет, в вашем случае цвет фона, затем настройте оттенок, насыщенность и значение. Используя это, вы можете очень легко создавать образцы цвета. Paint.Net бесплатен, и я использую его для этого все время, а также платные инструменты.

МотоУильямс
источник
0

Лично я не думаю, что мы сможем найти алгоритм для вычисления наиболее подходящего цвета текста, указав цвет фона.

Я думаю, что в настоящее время у художника должен быть список цветовых пар с хорошим качеством чтения, мы можем добавить их в таблицу и случайным образом установить одну из этих пар в качестве темы для чтения ...

это очень разумно, и мы не получим уродливых цветовых пар ...

мухоловка
источник