Обратные противоположные цвета

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

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

Есть ли такая функция?

Solutions Collecting From Web of "Обратные противоположные цвета"

Я обнаружил, что лучшим решением для меня является преобразование значений RGB в значения YIQ . Поскольку нас интересует только значение яркости (представленное Y), выполняется один расчет: Y = (299*R + 587*G + 114*B)/1000 . Код Java для этого будет выглядеть так:

 public static Color getContrastColor(Color color) { double y = (299 * color.getRed() + 587 * color.getGreen() + 114 * color.getBlue()) / 1000; return y >= 128 ? Color.black : Color.white; } 

Вы можете видеть, что он просто решает использовать черный или белый, исходя из яркости исходного цвета. И результат работает очень красиво, на мой взгляд. Веса (299, 587, 114) пропорциональны чувствительности глаз (или, скорее, чувствительности сетчатки) к соответствующему цвету.

Используйте дополнительный цвет :

Алго прост, вычтите каждый компонент цвета из 255, чтобы получить новые цветовые компоненты

 Color textColor = Color.rgb(255-Color.red(bgColor), 255-Color.green(bgColor), 255-Color.blue(bgColor)); 

—– EDIT (поскольку дополнение на основе RGB может не работать всегда ——–

Эти две ссылки очень полезны и по теме:

http://www.splitbrain.org/blog/2008-09/18-calculating_color_contrast_with_php

http://24ways.org/2010/calculating-color-contrast

Основываясь на решении Marks, я бы предложил:

 public static int getComplementaryColor(int colorToInvert) { float[] hsv = new float[3]; Color.RGBToHSV(Color.red(colorToInvert), Color.green(colorToInvert), Color.blue(colorToInvert), hsv); hsv[0] = (hsv[0] + 180) % 360; return Color.HSVToColor(hsv); } 

И дополнительно я теперь создал аналогичный метод для расчета фона по умолчанию для заданного цвета:

 public static int getContrastVersionForColor(int color) { float[] hsv = new float[3]; Color.RGBToHSV(Color.red(color), Color.green(color), Color.blue(color), hsv); if (hsv[2] < 0.5) { hsv[2] = 0.7f; } else { hsv[2] = 0.3f; } hsv[1] = hsv[1] * 0.2f; return Color.HSVToColor(hsv); } 

У меня это работает, я думаю 🙂

Вот функция:

 public static int OpposeColor(int ColorToInvert) { int RGBMAX = 255; float[] hsv = new float[3]; float H; Log.i("HSV_H", "Start Color=" + ColorToInvert); Color.RGBToHSV( Color.red( ColorToInvert), RGBMAX - Color.green( ColorToInvert), Color.blue(ColorToInvert), hsv); Log.i("HSV_H", "Hue=" + hsv[0]); Log.i("HSV_H", "Saturation=" + hsv[1]); Log.i("HSV_H", "Value=" + hsv[2]); H = (float) (hsv[0] + 0.5); if (H > 1) H -= 1; Log.i("HSV_H", "Hue2=" + H); Log.i("HSV_H", "Color=" + Color.HSVToColor(hsv )); return Color.HSVToColor(hsv ); } 

Целочисленное решение:

 public static int getContrastColor(int color) { double y = (299 * Color.red(color) + 587 * Color.green(color) + 114 * Color.blue(color)) / 1000; return y >= 128 ? Color.BLACK : Color.WHITE; } 

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

У меня нет рабочего алгоритма для совместного использования, но вы можете попробовать что-то вроде:

 int threshold = 50; if(r < threshold && g < threshold && b < threshold) { // set your font color to white } else { // set your font color to black } 

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

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