Jak znaleźć dobrze wyglądający kolor czcionki, jeśli znany jest kolor tła? [Zamknięte]

86

Wydaje się, że istnieje tak wiele aplikacji internetowych z kołem kolorów, próbnikiem kolorów i dopasowywaniem kolorów, w których podajesz jeden kolor, a oni znajdują kilka innych kolorów, które utworzą harmonijny układ, gdy są używane w połączeniu. Jednak większość z nich koncentruje się tylko na kolorach tła, a każdy tekst drukowany na każdym kolorze tła (jeśli tekst jest w ogóle drukowany na podglądzie) jest czarny lub biały.

Mój problem jest inny. Znam kolor tła, którego chcę użyć dla obszaru tekstowego. Potrzebuję pomocy przy wyborze kilku kolorów (im więcej, tym weselej), których mogę użyć jako kolorów czcionki na tym tle. Najważniejsze jest to, że kolor zapewni czytelność czcionki (kontrast nie będzie zbyt niski, może też nie być zbyt wysoki, aby oczy nie były zestresowane) i oczywiście połączenie pierwszego planu i tła po prostu wygląda dobrze.

Czy ktoś wie o takiej aplikacji? Wolę aplikację internetową niż wszystko, co muszę pobrać. Dzięki.

Mecki
źródło

Odpowiedzi:

39

Jeśli potrzebujesz algorytmu, spróbuj tego: Zamień kolor z przestrzeni RGB na przestrzeń HSV (Barwa, Nasycenie, Wartość). Jeśli Twój framework UI nie może tego zrobić, przeczytaj ten artykuł: http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV

Odcień jest w [0,360). Aby znaleźć „przeciwny” kolor (pomyśl o kole kolorów), po prostu dodaj 180 stopni:

h = (h + 180) % 360;

Aby uzyskać nasycenie i wartość, odwróć je:

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

Konwertuj z powrotem na RGB. Powinno to zawsze zapewniać wysoki kontrast, nawet jeśli większość kombinacji będzie wyglądać brzydko.

Jeśli chcesz uniknąć „brzydkiej” części, stwórz tabelę z kilkoma „dobrymi” kombinacjami, znajdź tę z najmniejszą różnicą

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

i użyj tego.

Aaron Digulla
źródło
4

Okej, to wciąż nie jest najlepsze możliwe rozwiązanie, ale miło na początek. Napisałem małą aplikację w języku Java, która oblicza współczynnik kontrastu dwóch kolorów i przetwarza tylko kolory o współczynniku 5: 1 lub lepszym - ten współczynnik i formuła, której używam, zostały wydane przez W3C i prawdopodobnie zastąpią obecne zalecenie (które Uważam za bardzo ograniczone). Tworzy plik w bieżącym katalogu roboczym o nazwie „selected-font-colors.html” z wybranym kolorem tła i wierszem tekstu w każdym kolorze, który przeszedł ten test W3C. Oczekuje jednego argumentu, jakim jest kolor tła.

Np. Możesz to tak nazwać

java FontColorChooser 33FFB4

następnie otwórz wygenerowany plik HTML w dowolnej przeglądarce i wybierz kolor z listy. Wszystkie podane kolory przeszły test W3C dla tego koloru tła. Możesz zmienić odcięcie, zastępując 5 dowolną liczbą (niższe liczby pozwalają na słabsze kontrasty, np. 3 zapewni tylko kontrast 3: 1, 10 zapewni, że będzie to co najmniej 10: 1), a także możesz odciąć, aby uniknąć zbyt dużych kontrastów (upewniając się, że jest mniejsza niż określona liczba), np. dodanie

|| cDiff > 18.0

do klauzuli if sprawi, że kontrast nie będzie zbyt ekstremalny, ponieważ zbyt skrajne kontrasty mogą stresować twoje oczy. Oto kod i baw się dobrze :-)

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
źródło
Plus jeden, obliczenie kontrastu, dokładnie to, czego szukałem.
Max Kielland
2

To interesujące pytanie, ale nie sądzę, aby było to faktycznie możliwe. To, czy dwa kolory „pasują” jako kolory tła i pierwszego planu, zależy od technologii wyświetlania i fizjologicznych cech ludzkiego wzroku, ale przede wszystkim od osobistych upodobań ukształtowanych przez doświadczenie. Szybki przegląd MySpace jasno pokazuje, że nie wszyscy ludzie postrzegają kolory w ten sam sposób. Nie sądzę, aby był to problem, który można rozwiązać algorytmicznie, chociaż może istnieć ogromna baza danych zawierająca dopuszczalne pasujące kolory.

MusiGenesis
źródło
2

Zaimplementowałem coś podobnego z innego powodu - był to kod informujący użytkownika końcowego, czy wybrane przez nich kolory pierwszego planu i tła spowodują nieczytelny tekst. Aby to zrobić, zamiast sprawdzać wartości RGB, przekonwertowałem wartość koloru na HSL / HSV, a następnie eksperymentalnie określiłem, jaki był mój punkt odcięcia dla czytelności podczas porównywania wartości fg i bg. To jest coś, co możesz chcieć / musisz rozważyć.

RedFilter
źródło
2

W ostatniej aplikacji, którą wykonałem, użyłem odwróconych kolorów. Mając pod ręką wartości r, g i b, po prostu oblicz (w tym przykładzie zakres kolorów waha się od 0 do 255):

r = 127-(r-127) and so on.
Flávio Batista
źródło
1

Odpowiedź na moje własne pytanie może być dziwna, ale oto kolejny naprawdę fajny wybór kolorów, którego nigdy wcześniej nie widziałem. To też nie rozwiązuje mojego problemu: - ((((chociaż wydaje mi się, że jest dużo fajniej niż te, które już znam.

http://www.colorjack.com/

Po prawej stronie w obszarze Narzędzia wybierz „Kula kolorów”, bardzo potężną i konfigurowalną sferę (zobacz, co możesz zrobić z wyskakującymi okienkami u góry), „Kolorowa galaktyka”. Nadal nie jestem pewien, jak to działa, ale wygląda fajnie i "Color Studio" też jest fajne. Ponadto może eksportować do wszystkich rodzajów formatów (np. Illustrator lub Photoshop itp.)

A co powiesz na to, że wybieram tam kolor tła, pozwalam mu stworzyć kolor uzupełniający (z pierwszego wyskakującego okienka) - powinien mieć najwyższy kontrast, a tym samym być najlepiej czytelny, teraz wybierz kolor uzupełniający jako kolor główny i wybierz neutralny? Hmmm ... też niezbyt fajnie, ale jest coraz lepiej ;-)

Mecki
źródło
Nie, wcale nie jest dziwne odpowiadanie na własne pytanie. Skończyło się na tym, że zrobiłem to kilka razy i uzyskanie odpowiedzi tylko poprawia społeczność.
Dillie-O
0

Czy zastanawiałeś się, czy użytkownik Twojej aplikacji może wybrać własną kolorystykę? Bez wątpienia nie będziesz w stanie zadowolić wszystkich użytkowników swoim wyborem, ale możesz pozwolić im znaleźć to, co ich zadowoli.

koks
źródło
1
Nie ma nic złego w pozwoleniu użytkownikowi na podjęcie decyzji, ale powinienem przynajmniej dołączyć przydatny domyślny motyw kolorystyczny, prawda? Nie może być tak, że jest nieczytelny i brzydki domyślnie jak diabli, dopóki każdy użytkownik tego nie naprawi ;-)
Mecki
0

Podobnie jak w przypadku sugestii @Aaron Digulla, z tą różnicą, że zasugerowałbym narzędzie do projektowania graficznego, wybierz kolor bazowy, w twoim przypadku kolor tła, a następnie dostosuj odcień, nasycenie i wartość. Dzięki temu możesz bardzo łatwo tworzyć próbki kolorów. Paint.Net jest darmowy i używam go do tego cały czas, a narzędzia płatne również to zrobią.

MotoWilliams
źródło
0

Osobiście nie sądzę, abyśmy mogli znaleźć algorytm obliczania najlepiej dopasowanego koloru tekstu, określając kolor tła.

Myślę, że obecnie artysta powinien mieć listę par kolorów, które mają dobrą jakość czytania, możemy dodać je do tabeli i ustawić jedną z tych par losowo jako nasz temat do czytania ...

jest to rozsądne i nie otrzymamy brzydkich par kolorów ....

flypig
źródło