Преобразование цвета RGBA в RGB
Как преобразовать кортеж цвета RGBA, пример (96, 96, 96, 202), к соответствующему цветному кортежу RGB?
Edit:
Я хочу получить значение RGB, которое наиболее похоже на кортеж RGBA визуально на белом фоне.
6 ответов:
Я поддержал ответ Йоханнеса, потому что он прав насчет этого.
* было высказано несколько замечаний о том, что мой первоначальный ответ не был правильным. Это сработало, если Альфа-значения были инвертированы от нормального. По определению, однако, это не будет работать в большинстве случаев. Поэтому я обновил приведенную ниже формулу, чтобы она была правильной для обычного случая. Это в конечном итоге равно ответу @hkurabko ниже *
более конкретный ответ, однако, включает в себя альфа значение в фактический результат цвета на основе непрозрачного цвета фона (или "матовый", как это называется).
есть алгоритм для этого (с этой ссылка на Википедию):
- Нормализуйте значения RGBA так, чтобы они были между 0 и 1 - просто разделите каждое значение на 255, чтобы сделать это. Мы будем называть результат
Source
.- Нормализуйте также матовый цвет (черный, белый любой). Мы будем называть результат
BGColor
Примечание - если цвет фона также прозрачен, то вам придется сначала повторить процесс для этого (опять же, выбрав матовый), чтобы получить исходный RGB для этой операции.теперь преобразование определяется как (в полном коде psuedo здесь!):
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 (это чрезмерная экспозиция и есть более сложные алгоритмы, связанные с этим, которые включают в себя обработку всего изображения и т. д.).EDIT: в своем вопросе вы сказали, что хотите белый фон - в этом случае просто исправьте 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)
эта измененная версия отлично работает для меня, потому что в prev. версия rgba(0,0,0,0) с матовым rgb(ff,ff,ff) будет изменена на rgb (0,0,0).
Это зависит от используемого цветового пространства. Если RGBA находится в предварительно умноженном цветовом пространстве и полупрозрачен, вам нужно разделить Альфа, чтобы получить правильный цвет RGB. Если цвет находится в предварительно не умноженном цветовом пространстве, то вы можете просто отбросить альфа-канал.
в моем случае я хотел преобразовать изображение RGBA в RGB, и следующее работало так же, как и ожидалось:
rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
вот удобная функция 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); }
вот некоторые 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; }