Подтвердить что ты не робот

Программно выбирайте высококонтрастные цвета

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

Посмотрите это решение PHP: Вычисление цветового контраста с PHP Андреасом Гором. Его можно портировать на любой язык, конечно.

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

Ответ 4

Вы можете использовать метод GetBrightness() в классе Color. Он возвращает значение float от 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;

Ответ 5

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

  // Black background is a special case.  It 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);
  }

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

Ответ 7

Если вы перевернете все биты, вы получите "противоположный" цвет, который будет довольно хорошим контрастом.

Я считаю, что оператор ~ в С#:

R2 = ~R1;
G2 = ~G1;
B2 = ~B1;

Ответ 8

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

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) не очень хорош.

Ответ 9

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

Ответ 10

Благодаря @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);
        }

Ответ 11

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

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

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

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