Как преобразовать набор цветов RGBA, например (96, 96, 96, 202), в соответствующий набор цветов RGB?
Редактировать:
Я хочу получить значение RGB, которое больше всего похоже на кортеж RGBA визуально на белом фоне.
Как преобразовать набор цветов RGBA, например (96, 96, 96, 202), в соответствующий набор цветов RGB?
Редактировать:
Я хочу получить значение RGB, которое больше всего похоже на кортеж RGBA визуально на белом фоне.
Ответы:
Я поддержал ответ Йоханнеса, потому что он прав в этом.
* Было высказано несколько комментариев о том, что мой первоначальный ответ был неправильным. Это работало, если альфа-значения были инвертированы по сравнению с нормальными. Однако по определению в большинстве случаев это не сработает. Поэтому я обновил приведенную ниже формулу, чтобы она соответствовала нормальному случаю. Это в конечном итоге равно ответу @ hkurabko ниже *
Однако более конкретный ответ включает альфа-значение в фактический результат цвета на основе непрозрачного цвета фона (или «матового», как его называют).
Для этого есть алгоритм (из этой ссылки в википедии):
Source
.BGColor
Note - если цвет фона также является прозрачным, вам придется сначала повторить процесс для этого (опять же, выбрав матовый цвет), чтобы получить исходный RGB для этой операции.Теперь преобразование определяется как (здесь полный псевдокод!):
Source => Target = (BGColor + Source) =
Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R)
Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G)
Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)
Чтобы получить окончательные значения 0-255 Target
, просто умножьте все нормализованные значения на 255, убедившись, что вы ограничены 255, если какое-либо из комбинированных значений превышает 1,0 (это чрезмерная экспозиция, и есть более сложные алгоритмы, решающие эту проблему. которые включают обработку всего изображения и т. д.).
РЕДАКТИРОВАТЬ: В своем вопросе вы сказали, что хотите белый фон - в этом случае просто исправьте BGColor на 255,255,255.
хм ... что касается
http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
решение, предоставленное Андрасом Золтаном, следует немного изменить на:
Source => Target = (BGColor + Source) =
Target.R = ((1 - Source.A) * BGColor.R) + (Source.A * Source.R)
Target.G = ((1 - Source.A) * BGColor.G) + (Source.A * Source.G)
Target.B = ((1 - Source.A) * BGColor.B) + (Source.A * Source.B)
Эта измененная версия мне подходит, потому что в пред. версия rgba (0,0,0,0) с матовым rgb (ff, ff, ff) будет изменена на rgb (0,0,0).
В моем случае я хотел преобразовать изображение RGBA в RGB, и следующее сработало так, как ожидалось:
rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
Это зависит от используемого вами цветового пространства. Если RGBA находится в предварительно умноженном цветовом пространстве и является полупрозрачным, вам необходимо разделить альфа-канал, чтобы получить правильный цвет RGB. Если цвет находится в цветовом пространстве без предварительного умножения, вы можете просто отказаться от альфа-канала.
Вот удобная функция SASS в соответствии с ответами Андраса и Хкурабко.
@function rgba_blend($fore, $back) {
$ored: ((1 - alpha($fore)) * red($back) ) + (alpha($fore) * red($fore));
$ogreen: ((1 - alpha($fore)) * green($back) ) + (alpha($fore) * green($fore));
$oblue: ((1 - alpha($fore)) * blue($back) ) + (alpha($fore) * blue($fore));
@return rgb($ored, $ogreen, $oblue);
}
Применение:
$my_color: rgba(red, 0.5); // build a color with alpha for below
#a_div {
background-color: rgba_blend($my_color, white);
}
mix($color, white, $alpha*100)
Вот код Java (работает на Android API 24):
//int rgb_background = Color.parseColor("#ffffff"); //white background
//int rgba_color = Color.parseColor("#8a000000"); //textViewColor
int defaultTextViewColor = textView.getTextColors().getDefaultColor();
int argb = defaultTextViewColor;
int alpha = 0xFF & (argb >> 24);
int red = 0xFF & (argb >> 16);
int green = 0xFF & (argb >> 8);
int blue = 0xFF & (argb >> 0);
float alphaFloat = (float)alpha / 255;
String colorStr = rgbaToRGB(255, 255, 255, red, green, blue, alphaFloat);
функция:
protected String rgbaToRGB(int rgb_background_red, int rgb_background_green, int rgb_background_blue,
int rgba_color_red, int rgba_color_green, int rgba_color_blue, float alpha) {
float red = (1 - alpha) * rgb_background_red + alpha * rgba_color_red;
float green = (1 - alpha) * rgb_background_green + alpha * rgba_color_green;
float blue = (1 - alpha) * rgb_background_blue + alpha * rgba_color_blue;
String redStr = Integer.toHexString((int) red);
String greenStr = Integer.toHexString((int) green);
String blueStr = Integer.toHexString((int) blue);
String colorHex = "#" + redStr + greenStr + blueStr;
//return Color.parseColor(colorHex);
return colorHex;
}