Jak przekonwertować krotkę kolorów RGBA, na przykład (96, 96, 96, 202), na odpowiednią krotkę kolorów RGB?
Edytować:
To, czego chcę, to uzyskać wartość RGB, która jest najbardziej podobna do krotki RGBA wizualnie na białym tle.
Jak przekonwertować krotkę kolorów RGBA, na przykład (96, 96, 96, 202), na odpowiednią krotkę kolorów RGB?
Edytować:
To, czego chcę, to uzyskać wartość RGB, która jest najbardziej podobna do krotki RGBA wizualnie na białym tle.
Odpowiedzi:
Głosowałem za odpowiedzią Johannesa, ponieważ ma rację.
* Pojawiło się kilka komentarzy, że moja pierwotna odpowiedź była nieprawidłowa. Działało, jeśli wartości alfa zostały odwrócone od normalnych. Jednak z definicji to nie zadziała w większości przypadków. Dlatego zaktualizowałem poniższy wzór, aby był poprawny dla normalnego przypadku. To kończy się na równi z odpowiedzią @ hkurabko poniżej *
Bardziej szczegółowa odpowiedź polega jednak na włączeniu wartości alfa do rzeczywistego wyniku koloru na podstawie nieprzezroczystego koloru tła (lub „matowego”, jak to się nazywa).
Jest na to algorytm (z tego linku wikipedii):
Source
.BGColor
Uwaga - jeśli kolor tła jest również przezroczysty, to najpierw będziesz musiał powtórzyć ten proces (ponownie, wybierając matę), aby uzyskać źródło RGB dla tej operacji.Teraz konwersja jest zdefiniowana jako (w pełnym kodzie pseudo tutaj!):
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)
Aby uzyskać ostateczne wartości 0-255 Target
, po prostu pomnóż wszystkie znormalizowane wartości z powrotem przez 255, upewniając się, że ograniczasz do 255, jeśli którakolwiek z połączonych wartości przekracza 1,0 (jest to nadmierna ekspozycja i istnieją bardziej złożone algorytmy radzące sobie z tym które obejmują przetwarzanie całego obrazu itp.).
EDYCJA: W swoim pytaniu powiedziałeś, że chcesz mieć białe tło - w takim przypadku po prostu ustaw BGColor na 255,255,255.
hm ... w odniesieniu do
http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
rozwiązanie dostarczone przez Andrasa Zoltana należy nieznacznie zmienić na:
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)
U mnie ta zmieniona wersja działa dobrze, ponieważ w poprzedniej wersji. wersja rgba (0,0,0,0) z matowym rgb (ff, ff, ff) zostanie zmieniona na rgb (0,0,0).
W moim przypadku chciałem przekonwertować obraz RGBA na RGB, a poniższe działały zgodnie z oczekiwaniami:
rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
Oto wygodna funkcja SASS zgodna z odpowiedziami Andrasa i hkurabko.
@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);
}
Stosowanie:
$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)
Oto kod java (działa na 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);
funkcjonować:
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;
}