web-dev-qa-db-fra.com

Convertir la couleur RGBA en RGB

Comment convertir un tuple de couleur RGBA, exemple (96, 96, 96, 202), en tuple de couleur RVB correspondant?

Modifier:

Ce que je veux, c'est obtenir une valeur RVB qui ressemble le plus au tuple RGBA visuellement sur fond blanc.

72
jack

J'ai voté pour la réponse de Johannes parce qu'il a raison à ce sujet.

* Quelques commentaires ont été soulevés selon lesquels ma réponse d'origine n'était pas correcte. Cela a fonctionné 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 être correcte pour le cas normal. Cela finit par être égal à la réponse de @ hkurabko ci-dessous *

Une réponse plus spécifique, cependant, incorpore la valeur alpha dans le résultat de la couleur réelle sur la base d'une couleur d'arrière-plan opaque (ou `` Matte '' comme on l'appelle).

Il existe un algorithme pour cela (à partir de ce lien wikipedia):

  • Normalisez les valeurs RGBA afin qu'elles soient toutes comprises entre 0 et 1 - divisez simplement chaque valeur par 255 pour ce faire. Nous appellerons le résultat Source.
  • Normaliser également la couleur mate (noir, blanc, peu importe). Nous appellerons le résultat BGColor Remarque - si la couleur d'arrière-plan est également transparente, alors vous devrez répéter le processus pour que le premier (encore une fois, choisir un cache) pour obtenir le RVB source pour cette opération.
  • Maintenant, la conversion est définie comme (en code pseudo 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 de 0 à 255 pour Target, il vous suffit de multiplier toutes les valeurs normalisées par 255, en vous assurant de plafonner à 255 si l'une des valeurs combinées dépasse 1,0 (il s'agit d'une surexposition et il y a des algorithmes plus complexes traitant de cela qui impliquent le traitement de l'image entière, etc.).

EDIT: Dans votre question, vous avez dit que vous voulez un fond blanc - dans ce cas, fixez simplement BGColor à 255,255,255.

86
Andras Zoltan

hm ... concernant

http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending

la solution fournie par Andras Zoltan devrait être légèrement modifiée pour:

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 bien pour moi, car dans la précédente. la version rgba (0,0,0,0) avec RGB mat (ff, ff, ff) sera remplacée par rgb (0,0,0).

37
hkurabko

Cela dépend de l'espace colorimétrique que vous utilisez. Si le RGBA est dans un espace colorimétrique pré-multiplié et est semi-transparent, vous devez diviser alpha pour obtenir la couleur RVB correcte. Si la couleur est dans un espace colorimétrique non pré-multiplié, vous pouvez simplement supprimer le canal alpha.

4
kusma

Dans mon cas, je voulais convertir une image RGBA en RVB et ce qui suit a fonctionné comme prévu:

rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
3
SulabhMatele

Voici quelques Java code (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);

une 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;
}
1
live-love

Voici une fonction SASS pratique conformément aux réponses d'Andras et de 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);
}

Usage:

$my_color: rgba(red, 0.5); // build a color with alpha for below

#a_div {
  background-color: rgba_blend($my_color, white);
}
1
Rohanthewiz