Использование цвета и color.darker в Android?

Хорошо, поэтому у меня есть целочисленная переменная в моем приложении. Это значение цвета, которое задается цветовым подборщиком в моих предпочтениях. Теперь мне нужно использовать как этот цвет, так и более темную версию любого цвета, который может быть.

Теперь я знаю, что в стандартной Java существует метод Color.darker (), но, похоже, в Android нет эквивалента. Кто-нибудь знает об эквиваленте или обходных решениях?

Проще всего, я думаю, было бы преобразовать в HSV, потемнение там и преобразовать обратно:

float[] hsv = new float[3]; int color = getColor(); Color.colorToHSV(color, hsv); hsv[2] *= 0.8f; // value component color = Color.HSVToColor(hsv); 

Чтобы облегчить, простой подход может заключаться в том, чтобы умножить компонент значения на что-то> 1.0. Однако вам нужно будет закрепить результат в диапазоне [0.0, 1.0]. Кроме того, простое умножение не будет осветлять черный.

Поэтому лучшим решением является: уменьшите разницу от 1,0 компонента значения, чтобы осветлить:

 hsv[2] = 1.0f - 0.8f * (1.0f - hsv[2]); 

Это полностью совпадает с подходом к потемнению, просто используя 1 как источник вместо 0. Он работает, чтобы осветлить любой цвет (даже черный) и не требует никакого зажима. Это может быть упрощено:

 hsv[2] = 0.2f + 0.8f * hsv[2]; 

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

Вот что я создал:

 /** * Returns darker version of specified color. */ public static int darker (int color, float factor) { int a = Color.alpha( color ); int r = Color.red( color ); int g = Color.green( color ); int b = Color.blue( color ); return Color.argb( a, Math.max( (int)(r * factor), 0 ), Math.max( (int)(g * factor), 0 ), Math.max( (int)(b * factor), 0 ) ); } 

Ответ Теда на облегчение цвета не работал для меня, поэтому вот решение, которое может помочь кому-то другому:

 /** * Lightens a color by a given factor. * * @param color * The color to lighten * @param factor * The factor to lighten the color. 0 will make the color unchanged. 1 will make the * color white. * @return lighter version of the specified color. */ public static int lighter(int color, float factor) { int red = (int) ((Color.red(color) * (1 - factor) / 255 + factor) * 255); int green = (int) ((Color.green(color) * (1 - factor) / 255 + factor) * 255); int blue = (int) ((Color.blue(color) * (1 - factor) / 255 + factor) * 255); return Color.argb(Color.alpha(color), red, green, blue); } 

Процедура Java Color для darken и brighten не требует ничего особенного. Фактически, это просто развернутое понимание того, какая яркость применяется к соответствующим цветам. То есть вы можете просто взять красные, зеленые, синие значения. Умножьте их на любой коэффициент, убедитесь, что они правильно попали в гамму.

Ниже приведен код, найденный в classе Color.

 private static final double FACTOR = 0.7; //... public Color darker() { return new Color(Math.max((int)(getRed() *FACTOR), 0), Math.max((int)(getGreen()*FACTOR), 0), Math.max((int)(getBlue() *FACTOR), 0), getAlpha()); } 

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

 public int crimp(int c) { return Math.min(Math.max(c, 0), 255); } public int darken(int color) { double factor = 0.7; return (color & 0xFF000000) | (crimp((int) (((color >> 16) & 0xFF) * factor)) << 16) | (crimp((int) (((color >> 8) & 0xFF) * factor)) << 8) | (crimp((int) (((color) & 0xFF) * factor))); } 

Обратите внимание, что это то же самое, что только увеличение яркости в HSB, B - просто самый яркий фактор, оттенок - это соотношение между различными цветами, а S - насколько они далеко друг от друга. Поэтому, если мы просто возьмем все цвета и умножим их на коэффициент, мы получим те же цвета в одном и том же миксе с немного более белым / черным в них.

Многие современные цветовые пространства также делают это с вычислением значения Y через различные цветовые компоненты, которые наилучшим образом приближают яркость. Таким образом, вы могли бы, если бы хотели преобразовать в лучшую форму Y или L через любой из современных цветовых пространств и преобразовать их, другие цветовые пространства имеют лучшую форму гамма в отношении того, насколько каждый цвет способствует реальной яркости, легкости, белизну, черноту или что-то другое, что цветовое пространство вызывает это. Это сделало бы лучшую работу, но для большинства целей это твердое.

Поэтому, в крайнем случае, вы можете сделать это, перейдя в Lab, уменьшив компонент L и преобразовывая его обратно.

Вот код для этого:

 static int darken(int color) { double factor = 0.7; double[] returnarray = new double[3]; convertRGBsRGB(returnarray, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), (color & 0xFF)); convertRGBXYZ(returnarray,returnarray[0], returnarray[1], returnarray[2]); convertXYZLab(returnarray,returnarray[0], returnarray[1], returnarray[2]); returnarray[0] *= factor; convertLabXYZ(returnarray,returnarray[0], returnarray[1], returnarray[2]); convertXYZRGB(returnarray,returnarray[0], returnarray[1], returnarray[2]); return (color & 0xFF000000) | convertsRGBRGB(returnarray); } static void convertRGBsRGB(double[] returnarray, int R, int G, int B) { double var_R = (((double) R) / 255.0d); //RGB from 0 to 255 double var_G = (((double) G) / 255.0d); double var_B = (((double) B) / 255.0d); returnarray[0] = var_R; returnarray[1] = var_G; returnarray[2] = var_B; } static int convertsRGBRGB(double[] sRGB) { int red = (int) (sRGB[0] * 255); int green = (int) (sRGB[1] * 255); int blue = (int) (sRGB[2] * 255); red = crimp(red); green = crimp(green); blue = crimp(blue); return (red << 16) | (green << 8) | blue; } public static int crimp(int v) { if (v > 0xff) { v = 0xff; } if (v < 0) { v = 0; } return v; } public static final double ref_X = 95.047; //ref_X = 95.047 Observer= 2°, Illuminant= D65 public static final double ref_Y = 100.000; //ref_Y = 100.000 public static final double ref_Z = 108.883;//ref_Z = 108.883 static void convertRGBXYZ(double[] returnarray, double var_R, double var_G, double var_B) { if (var_R > 0.04045) { var_R = Math.pow(((var_R + 0.055) / 1.055), 2.4); } else { var_R = var_R / 12.92; } if (var_G > 0.04045) { var_G = Math.pow(((var_G + 0.055) / 1.055), 2.4); } else { var_G = var_G / 12.92; } if (var_B > 0.04045) { var_B = Math.pow(((var_B + 0.055) / 1.055), 2.4); } else { var_B = var_B / 12.92; } var_R = var_R * 100; var_G = var_G * 100; var_B = var_B * 100; //Observer. = 2°, Illuminant = D65 double X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805; double Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722; double Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505; returnarray[0] = X; returnarray[1] = Y; returnarray[2] = Z; } static void convertXYZLab(double[] returnarray, double X, double Y, double Z) { double var_X = X / ref_X; double var_Y = Y / ref_Y; double var_Z = Z / ref_Z; if (var_X > 0.008856) { var_X = Math.cbrt(var_X); } else { var_X = (7.787 * var_X) + (16.0d / 116.0d); } if (var_Y > 0.008856) { var_Y = Math.cbrt(var_Y); } else { var_Y = (7.787 * var_Y) + (16.0d / 116.0d); } if (var_Z > 0.008856) { var_Z = Math.cbrt(var_Z); } else { var_Z = (7.787 * var_Z) + (16.0d / 116.0d); } double CIE_L = (116 * var_Y) - 16; double CIE_a = 500 * (var_X - var_Y); double CIE_b = 200 * (var_Y - var_Z); returnarray[0] = CIE_L; returnarray[1] = CIE_a; returnarray[2] = CIE_b; } static void convertLabXYZ(double[] returnarray, double CIE_L, double CIE_a, double CIE_b) { double var_Y = (CIE_L + 16) / 116; double var_X = CIE_a / 500 + var_Y; double var_Z = var_Y - CIE_b / 200; if ((var_Y * var_Y * var_Y) > 0.008856) { var_Y = (var_Y * var_Y * var_Y); } else { var_Y = (((var_Y - 16) / 116)) / 7.787; } if ((var_X * var_X * var_X) > 0.008856) { var_X = (var_X * var_X * var_X); } else { var_X = ((var_X - 16) / 116) / 7.787; } if ((var_Z * var_Z * var_Z) > 0.008856) { var_Z = (var_Z * var_Z * var_Z); } else { var_Z = ((var_Z - 16) / 116) / 7.787; } double X = ref_X * var_X; //ref_X = 95.047 Observer= 2°, Illuminant= D65 double Y = ref_Y * var_Y; //ref_Y = 100.000 double Z = ref_Z * var_Z; //ref_Z = 108.883 returnarray[0] = X; returnarray[1] = Y; returnarray[2] = Z; } static void convertXYZRGB(double[] returnarray, double X, double Y, double Z) { double var_X = X / 100; //X from 0 to 95.047 (Observer = 2°, Illuminant = D65) double var_Y = Y / 100; //Y from 0 to 100.000 double var_Z = Z / 100; //Z from 0 to 108.883 double var_R = (var_X * 3.2406) + (var_Y * -1.5372) + (var_Z * -0.4986); double var_G = (var_X * -0.9689) + (var_Y * 1.8758) + (var_Z * 0.0415); double var_B = (var_X * 0.0557) + (var_Y * -0.2040) + (var_Z * 1.0570); if (var_R > 0.0031308) { var_R = 1.055 * (Math.pow(var_R, (1f / 2.4f))) - 0.055; } else { var_R = 12.92 * var_R; } if (var_G > 0.0031308) { var_G = 1.055 * (Math.pow(var_G, (1f / 2.4f))) - 0.055; } else { var_G = 12.92 * var_G; } if (var_B > 0.0031308) { var_B = 1.055 * (Math.pow(var_B, (1f / 2.4f))) - 0.055; } else { var_B = 12.92 * var_B; } returnarray[0] = var_R; returnarray[1] = var_G; returnarray[2] = var_B; } 

Мои линии линии делают то же самое, что и Color.darken (), это изображение образца набора цветов (эти цвета являются максимальным расстоянием от всех предыдущих цветов через CIE-LabD2000, просто используя их в качестве надежных наборов цветов).

Index Color, Color.darker () и мой основной darken (), все в ФАКТОР 0.7. индекс против темного и темного (они должны быть одинаковыми)

Далее для тех, кто предложил использовать Lab для затемнения,

Index Color, Color.darker () и Lab Darker (), все в ФАКТОРЕ 0,7. введите описание изображения здесь (это улучшение стоит времени сосать?)

  • Как получить текущий момент в формате ISO 8601 с датой, часом и минутой?
  • Вопрос о возврате дизайна Java try-finally
  • Преобразование String в массив int в java
  • Calendar.getInstance (TimeZone.getTimeZone («UTC»)) не возвращает время UTC
  • Java-язык с поддержкой Android
  • Почему в Android не работает «System.out.println»?
  • Метод сравнения нарушает его общий контракт в Java 7
  • Максимальный размер метода в java?
  • Как обновить TextView от другого classа
  • Как определить использование размера кучи приложения для Android
  • Нет доступного экземпляра типа Server.
  • Interesting Posts

    Linux: просмотр изображений с прозрачным окном?

    Как переименовать устройство принтера в Windows 7 64 бит

    Каковы параметры командной строки –start-group и -end-group?

    Какой код установки должен идти в Form Constructors по сравнению с событием Form Load?

    Где «Режим браузера» ушел из средств разработки Internet Explorer 11?

    Dot character ‘.’ в MVC Web API 2 для запроса, например api / people / STAFF.45287

    Является ли UnitOfWork равным транзакции? Или это больше?

    Как преобразовать входное значение в верхний регистр в угловом 2 (значение, передаваемое в ngControl)

    Как переименовать несколько файлов в нескольких папках с помощью одной команды

    Не удается установить Office в windows

    Итерирование атрибутов элементов с помощью jQuery

    Порядок методов расширения LINQ не влияет на производительность?

    java keylistener не вызван

    CSS ТОЛЬКО Анимация Кружок рисования с радиусом границы и прозрачным фоном

    Функция Microsoft Excel Filter

    Давайте будем гением компьютера.