Conversion couleur RGBA en RGB
comment convertir un RGBA tuple couleur, exemple (96, 96, 96, 202), à la couleur correspondante RVB tuple?
Edit:
ce que je veux est d'obtenir une valeur RGB qui est plus similaire à la RGBA tuple visuellement sur fond blanc.
6 réponses
J'ai rejeté la réponse de Johannes parce qu'il a raison.
* quelques commentaires ont été soulevées que ma réponse n'était pas correcte. Ça a marché si les valeurs alpha étaient inversées par rapport à la normale. Par définition, cependant, cela ne fonctionnera pas dans la plupart des cas. J'ai donc mis à jour la formule ci-dessous pour qu'elle soit correcte pour le cas normal. Cela se termine par être égal à la réponse de @hkurabko ci-dessous *
plus spécifique réponse, cependant, incorpore la valeur alpha dans le résultat de couleur réelle basée sur une couleur de fond opaque (ou "matte" comme il est appelé).
il y a un algorithme pour cela (de ce lien Wikipédia):
- Normalisez les valeurs RGBA de sorte qu'elles soient toutes entre 0 et 1 - divisez chaque valeur par 255 pour ce faire. Nous appellerons le résultat
Source
. - normaliser aussi le mat de couleur (noir, blanc quoi que ce soit). Nous appellerons le résultat
BGColor
Note - si la couleur de fond est également transparente, alors vous devrez recommencer le processus pour cette première (encore une fois, en choisissant une matte) pour obtenir le RVB source pour cette opération. -
maintenant, la conversion est définie comme (dans le code psuedo complet ici!):
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)
pour obtenir les valeurs finales 0-255 pour Target
vous multipliez simplement toutes les valeurs normalisées par 255, en vous assurant de plafonner à 255 si l'une des valeurs combinées dépasse 1,0 (ceci est une surexposition et il y a des algorithmes plus complexes traitant de cela qui impliquent le traitement d'image complète, etc.).
EDIT: dans votre question vous avez dit que vous vouliez un fond blanc - dans ce cas, il suffit de fixer BGColor à 255,255,255.
hm... au sujet de
http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
la solution fournie par Andras Zoltan doit être légèrement modifiée comme suit:
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)
cette version modifiée fonctionne très bien pour moi, parce que dans prev. la version rgba(0,0,0,0) avec matte rgb(ff,ff,ff) sera remplacée par rgb (0,0,0).
Cela dépend de l'espace de couleur que vous utilisez. Si le RGBA est dans l'espace couleur pré-multiplié et est semi-transparent, vous devez diviser alpha pour obtenir la couleur RGB correcte. Si la couleur est dans l'espace de couleur non pré-multiplié,alors vous pouvez simplement jeter le canal alpha.
dans mon cas, je voulais convertir une image RGBA en RGB et la suivante a fonctionné comme prévu:
rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
Voici une fonction Sass pratique en accord avec les réponses D'Andras et 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);
}
Utilisation:
$my_color: rgba(red, 0.5); // build a color with alpha for below
#a_div {
background-color: rgba_blend($my_color, white);
}
voici un peu de code java (fonctionne sur 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);
fonction:
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;
}