Программно выбирайте высококонтрастные цвета - PullRequest
23 голосов
/ 02 января 2009

Это должен быть простой вопрос, но я не смог найти способ заставить его работать.

По сути, у меня есть глупая локальная страница, которую я использую в своей веб-разработке. Когда я занимаюсь серфингом между нашим сервером разработки и моей локальной версией кода C # (перенаправленной из URL-адреса dev через файл хоста), я иногда забываю, на что указывает dev.foo.com - локальный или серверный.

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

Эта страница делает много вещей случайным образом (в том числе генерирует начальную статистику персонажа для D & D), включая установку случайного цвета фона. Я делаю это, генерируя 3 случайных числа от 0 до 255 и устанавливая их в качестве значения RGB для цвета фона тела в CSS.

Учитывая 3 дюйма R, G и B, как мне определить R2, G2 и B2 таким образом, чтобы второй цвет имел высокую контрастность с первым? Мне нравится, когда у страницы случайные цвета фона (это не дает мне привыкнуть к виду целевой страницы), но мне также нравится читать текст.

Ответы [ 11 ]

21 голосов
/ 02 января 2009

Вам нужна разница в яркости, чтобы текст был читабельным, поскольку само цветовое зрение имеет слишком низкое разрешение.

Итак, в качестве алгоритма я бы предложил следующее:

  • Выберите случайный цвет фона.

  • Затем решите, будет ли это светлый или темный цвет. Например, вы можете проверить, является ли среднее из трех основных цветов больше или равно 128.

  • Для светлого цвета используйте черный текст, для темного белого текста.

6 голосов
/ 02 января 2009

«Контраст» - это загруженное слово. Если вы просто хотите прочитать текст, то одним из простых способов является работа в цветовом пространстве на основе яркости, таком как HSL, и выбор цветов переднего плана и фона с большими различиями в яркости.

Преобразование между HSL и RGB хорошо известно - подробности см. В Википедии.

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

3 голосов
/ 01 июня 2009

Ознакомьтесь с этим решением PHP: Расчет цветового контраста с помощью PHP . Автор Andreas Gohr. Конечно, его можно перенести на любой язык.

У него также есть очень хорошая демонстрация его анализатора контраста, где вы можете найти несколько минимальных уровней контрастности для работы.

2 голосов
/ 19 марта 2012

Вы можете использовать метод GetBrightness() в классе Color. Возвращает значение с плавающей запятой от 0,0 (яркость черного) до 1,0 (белое). Простое решение будет:

var color1 = new Color.FromArgb(r1, g1, b1);
var brightness = color1.GetBrightness();

var color2 = brightness > 0.5 ? Color.Black : Color.White;
1 голос
/ 15 декабря 2018

В этих ответах более или менее предлагается использовать один из двух или трех вариантов цвета в зависимости от того, является ли цвет ярким или темным.

Я использую немного другой подход, и в моем случае он работал элегантно. Вот реализация.

 int color = your_color;
 contrastColor = Color.rgb(255-(color >> 16)&0xFF, 255-(color >> 8)&0xFF, 255- color&0xFF);

Это просто и замечательно.

1 голос
/ 02 января 2009

Есть несколько хороших ресурсов (и алгоритмов) для решения этой проблемы на http://juicystudio.com/article/luminositycontrastratioalgorithm.php

1 голос
/ 02 января 2009

Я сделал что-то подобное в приложении для Palm OS. Это то, что я придумал. Он не дает вам «высококонтрастных» цветов, но дает вам цвет фона, который достаточно отличается от цвета текста, чтобы быть вполне читабельным:

  // Black background is a special case.  It's fairly likely to occur and 
  // the default color shift we do isn't very noticeable with very dark colors.
  if (backColor.r < 0x20 && backColor.g < 0x20 && backColor.b < 0x20)
  {
      textColor.r = backColor.r + 0x20;
      textColor.g = backColor.g + 0x20;
      textColor.b = backColor.b + 0x20;
  }
  else
  {
      textColor.r = backColor.r + ((backColor.r < 128) ? 0x10 : -0x10);
      textColor.g = backColor.g + ((backColor.g < 128) ? 0x10 : -0x10);
      textColor.b = backColor.b + ((backColor.b < 128) ? 0x10 : -0x10);
  }

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

0 голосов
/ 15 июля 2014

Благодаря @ starblue !

Вот код C#, который я использую

 public static string GetContrastBlackOrWhiteColorAsHtmlColorCode(Color c)
        {
            System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml("transparent");

            try
            {
                if (c.R >= 128 && c.G >= 128 && c.B >= 128)
                {
                    return System.Drawing.ColorTranslator.ToHtml(Color.Black);
                }
                else
                {
                    return System.Drawing.ColorTranslator.ToHtml(Color.White);
                }
            }
            catch (Exception)
            {
            }

            return System.Drawing.ColorTranslator.ToHtml(color);
        }
0 голосов
/ 15 августа 2013
private Color GetContrastingColor(Color color)
{
    int r = color.R > 0 ? 256 - color.R : 255;
    int g = color.G > 0 ? 256 - color.G : 255;
    int b = color.B > 0 ? 256 - color.B : 255;
    return System.Drawing.Color.FromArgb(r, g, b);
}
0 голосов
/ 26 декабря 2012

Для лучшей контрастности используйте этот код

function lumdiff($R1,$G1,$B1,$R2,$G2,$B2){

    $L1 = 0.2126 * pow($R1/255, 2.2) +
          0.7152 * pow($G1/255, 2.2) +
          0.0722 * pow($B1/255, 2.2);

    $L2 = 0.2126 * pow($R2/255, 2.2) +
          0.7152 * pow($G2/255, 2.2) +
          0.0722 * pow($B2/255, 2.2);

    if($L1 > $L2){
        return ($L1+0.05) / ($L2+0.05);
    }else{
        return ($L2+0.05) / ($L1+0.05);
    }
}

function get_the_contrast($c1, $c2) {
    return (lumdiff(hexdec(substr($c1,0,2)),
        hexdec(substr($c1,2,2)),hexdec(substr($c1,4,2)),
        hexdec(substr($c2,0,2)),hexdec(substr($c2,2,2)),
        hexdec(substr($c2,4,2))));
}

Метод выше (AVG (красный, зеленый, синий)> 128) не очень хорош.

...