Як перетворити кортеж кольорів RGBA, приклад (96, 96, 96, 202), у відповідний кортеж кольорів RGB?
Редагувати:
Я хочу отримати значення RGB, яке найбільше нагадує візуально кортеж RGBA на білому тлі.
Як перетворити кортеж кольорів RGBA, приклад (96, 96, 96, 202), у відповідний кортеж кольорів RGB?
Редагувати:
Я хочу отримати значення RGB, яке найбільше нагадує візуально кортеж RGBA на білому тлі.
Відповіді:
Я підтримав відповідь Йоганнеса, бо він у цьому прав.
* Було висловлено кілька коментарів щодо того, що моя оригінальна відповідь була неправильною. Це спрацювало, якщо значення альфа були інвертовані від нормальних. Однак за визначенням це в більшості випадків не працює. Тому я оновив наведену нижче формулу, щоб вона була правильною для звичайного випадку. Це в кінцевому підсумку дорівнює відповіді @ hkurabko нижче *
Однак більш конкретна відповідь включає значення альфа у фактичний результат кольору на основі непрозорого кольору фону (або „матового“, як це згадується).
Для цього існує алгоритм (із цього посилання на Вікіпедію):
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)
Ця змінена версія добре працює для мене, тому що в попередній. версія 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;
}