Як знайти гарний колір шрифту, якщо колір фону відомий? [зачинено]


86

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

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

Хтось знав про таке застосування? Я віддаю перевагу веб-додатку перед усім, що мені потрібно завантажити. Дякую.

Відповіді:


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

Плюс один, розрахунок контрасту, саме те, що я шукав.
Max Kielland

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/

Праворуч, в розділі Інструменти виберіть «Кольорова сфера», дуже потужна та настроювана сфера (див., Що можна зробити зі спливаючими вікнами зверху), «Кольорова галактика», я все ще не впевнений, як це працює, але виглядає круто і "Color Studio" теж приємно. Далі він може експортувати у всі види форматів (наприклад, Illustrator або Photoshop тощо)

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


Ні, це зовсім не дивно відповісти на власне запитання, я сам вже кілька разів робив це, а отримання відповідей там лише покращує громаду.
Діллі-О

0

Чи роздумували ви про те, щоб дозволити користувачеві вашої програми вибрати власну колірну гамму? У обов'язковому порядку ви не зможете порадувати своїх користувачів своїм вибором, але ви можете дозволити їм знайти те, що їм подобається.


1
Немає нічого поганого в тому, щоб дозволити користувачеві вирішувати, але я все одно повинен, принаймні, включити корисну кольорову тему за замовчуванням, чи не так? Не може бути, що це нечитабельно і негарно, як пекло за замовчуванням, поки кожен користувач не виправить це ;-)
Мекі

0

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


0

Особисто я не думаю, що ми можемо знайти алгоритм для обчислення найбільш відповідного кольору тексту, вказавши колір фону.

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

це цілком розумно, і ми не отримаємо негарних кольорових пар ....

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.