Konvertieren Sie die RGBA-Farbe in RGB

79

Wie konvertiere ich ein RGBA-Farbtupel, Beispiel (96, 96, 96, 202), in ein entsprechendes RGB-Farbtupel?

Bearbeiten:

Ich möchte einen RGB-Wert erhalten, der dem RGBA-Tupel auf weißem Hintergrund am ähnlichsten ist.

Jack
quelle
3
Wäre das nicht einfach (96,96,96)?
Lazarus
24
Das hängt von der Farbe des Hintergrundpixels ab.
Frank Bollack
5
Möchten Sie nur den Alphakanal entfernen? Oder möchten Sie das RGB-Ergebnis der Überlagerung der RGBA mit einem (z. B.) weißen Hintergrund?
Ben James
1
Vielleicht möchten Sie die berühmte Zeitung "Compositing Digital Images" (von Porter und Duff) lesen, um alle Details zur Alpha-Komposition zu erfahren
kusma
Die Antwort von Andras Zoltan und hkurabko ist auch nützlich, um das Gegenteil zu berechnen. Ich meine, wenn Sie verschiedene Alpha-Mischfarben und ihre ursprünglichen Hintergründe (Matten) haben, können Sie die ursprüngliche RGBA-Farbe berechnen, nach der ich gesucht habe während;)
nacho4d

Antworten:

90

Ich habe Johannes 'Antwort positiv bewertet, weil er damit Recht hat.

* Es wurden einige Kommentare abgegeben, dass meine ursprüngliche Antwort nicht korrekt war. Es funktionierte, wenn die Alpha-Werte vom Normalen invertiert wurden. Per Definition funktioniert dies jedoch in den meisten Fällen nicht. Ich habe daher die folgende Formel aktualisiert, um für den Normalfall korrekt zu sein. Dies entspricht der Antwort von @ hkurabko unten *

Eine spezifischere Antwort bezieht jedoch den Alpha-Wert in das tatsächliche Farbergebnis ein, basierend auf einer undurchsichtigen Hintergrundfarbe (oder "matt", wie es genannt wird).

Hierfür gibt es einen Algorithmus (über diesen Wikipedia-Link):

  • Normalisieren Sie die RGBA-Werte so, dass sie alle zwischen 0 und 1 liegen. Teilen Sie dazu einfach jeden Wert durch 255. Wir werden das Ergebnis nennen Source.
  • Normalisieren Sie auch die matte Farbe (schwarz, weiß was auch immer). Wir nennen das Ergebnis. BGColor Hinweis : Wenn die Hintergrundfarbe ebenfalls transparent ist, müssen Sie den Vorgang zuerst wiederholen (erneut eine Matte auswählen), um das Quell-RGB für diesen Vorgang zu erhalten.
  • Jetzt ist die Konvertierung definiert als (hier im vollständigen Pseudocode!):

    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)
    

Um die endgültigen 0-255-Werte für TargetSie zu erhalten, multiplizieren Sie einfach alle normalisierten Werte mit 255 und stellen Sie sicher, dass Sie 255 begrenzen, wenn einer der kombinierten Werte 1,0 überschreitet (dies ist eine Überbelichtung, und es gibt komplexere Algorithmen, die sich damit befassen die eine Ganzbildverarbeitung usw. beinhalten).

BEARBEITEN: In Ihrer Frage sagten Sie, Sie möchten einen weißen Hintergrund - in diesem Fall korrigieren Sie BGColor einfach auf 255.255.255.

Andras Zoltan
quelle
9
In Anbetracht der Frage bearbeiten ist dies eine sehr genaue und gute Antwort. Ich habe meine gelöscht und hoffe, dass Sie
Joey
Ich denke, diese Antwort setzt voraus, dass die Hintergrundfarbe rgb und nicht rgba ist.
Leo
Dies ist ungewöhnlich, wenn man bedenkt, dass RGBA (0,0,0,1) vollständig undurchsichtig schwarz ist. Aber mit dem gegebenen Algorithmus wäre es vollständig transparentes Schwarz. Ich denke, eine Neuordnung des Algorithmus, um dies widerzuspiegeln, würde ihn zu einer hilfreicheren Ressource und einer besseren Antwort auf die Frage machen.
Bryan Rayner
1
@BryanRayner hat meiner Antwort einige Änderungen hinzugefügt. Ich bekomme regelmäßig Upvotes für diese Antwort, und es ist möglich, dass einige Leute sie finden und den Algorithmus selbst invertieren müssen. Es wäre besser, wenn es vollständiger wäre. Vielen Dank.
Andras Zoltan
2
Wenn noch jemand interessiert ist, können Sie mit dieser JSBin beobachten, wie die Farbe transformiert wird. Es ist auch bereit, als Javacript-Funktion verwendet zu werden. Ich habe BGColor als Weiß verwendet, weil ich das matte Konzept einfach nicht verstehe (sorry!). Der Link lautet wie folgt: jsbin.com/qocixeh/edit?html,js,console,output und auch ein Kern: gist.github.com/vladimirbrasil/bd139851ff757a1c8cb46fac93e733eb Hoffe, es hilft auch. Vielen Dank für die Antwort!
Vladimir Brasil
40

hm ... in Bezug auf

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

Die von Andras Zoltan bereitgestellte Lösung sollte leicht geändert werden in:

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)

Diese geänderte Version funktioniert gut für mich, weil in prev. Version rgba (0,0,0,0) mit mattem rgb (ff, ff, ff) wird in rgb (0,0,0) geändert.

hkurabko
quelle
Ich glaube du hast recht. Die Antwort von Wikipedia und Andras Zoltan ist etwas anders.
Nacho4d
1
Ich bin damit einverstanden, benutze diese Version, nicht die von @Andras Zoltan. Konvertieren Sie für ein Testszenario rgba (0,0,0, .7) in Hintergrund-rgb (255,255,255) unter Verwendung beider Formeln. hkurabkos forumala liefert eindeutig die richtige Antwort.
Ryre
4
Andras definiert 0 Alpha als undurchsichtig und 255 als transparent, während CSS es umgekehrt definiert. Diese Antwort funktioniert mit der CSS-Definition von Alpha.
Casey Chu
1
+1 Dies funktioniert mit der gebräuchlichsten Definition von Alpha (0 = transparent) wie OpenGL, SDL, Grafikeditoren.
DLight
+1 - und ich habe meine Antwort aktualisiert, um zu arbeiten, wobei Alpha auch diesbezüglich der richtige Weg ist. Ironischerweise stimme ich zu, dass meine ursprüngliche Antwort, obwohl sie ihren eigenen Sinn ergab, für die meisten Anwendungen nicht wirklich funktioniert hat, nachdem ich gerade versucht habe, meine Lösung zu verwenden, um dies zu tun.
Andras Zoltan
8

In meinem Fall wollte ich ein RGBA-Image in RGB konvertieren und Folgendes funktionierte wie erwartet:

rgbImage = cv2.cvtColor(npimage, cv2.COLOR_RGBA2RGB)
SulabhMatele
quelle
5

Dies hängt vom verwendeten Farbraum ab. Wenn sich die RGBA im vormultiplizierten Farbraum befindet und halbtransparent ist, müssen Sie Alpha teilen, um die richtige RGB-Farbe zu erhalten. Wenn sich die Farbe im nicht vormultiplizierten Farbraum befindet, können Sie den Alphakanal einfach verwerfen.

Kusma
quelle
1

Hier ist eine praktische SASS-Funktion gemäß den Antworten von Andras und 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);
}

Verwendung:

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

#a_div {
  background-color: rgba_blend($my_color, white);
}
Rohanthewiz
quelle
in sass können wir verwenden:mix($color, white, $alpha*100)
S.Serpooshan
1

Hier ist ein Java-Code (funktioniert mit 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);

Funktion:

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;
}
Live-Liebe
quelle