2012-07-23 12 views
6

Mögliche Duplizieren unter:
Convert RGBA color to RGBConvert RGBA in RGB-Hintergrund in Betracht

Ich versuche, eine RGBA Farbe zu konvertieren, mit einem alpha < 1 in eine feste RGB-Darstellung unter Berücksichtigung der Hintergrundfarbe.

Mit dem Algorithmus this question bekomme ich die korrekte Umwandlung in eine feste RGB-Farbe - aber nur wenn Alpha = 0,5.

Hier ist mein Testcode:

<!DOCTYPE html> 
<html> 
<head></head> 
<body> 
    <script type="text/javascript"> 
    // Basic RGB(A) to CSS property value 
    function _toString(obj) { 
     var type = 'rgb', out = obj.red + ', ' + obj.green + ', ' + obj.blue; 

     if (obj.alpha !== undefined) { 
      type += 'a'; 
      out += ', ' + obj.alpha; 
     } 

     return type + '(' + out + ')'; 
    } 

    // Background color, assume this is always RGB 
    var bg = {red: 255, green: 51, blue: 0}; 
    // RGBA color 
    var RGBA = {red: 0, green: 102, blue: 204, alpha: 0}; 
    // Output RGB 
    var RGB = {red: null, green: null, blue: null}; 
    // Just a cache... 
    var alpha; 

    while (RGBA.alpha < 1) { 
     alpha = 1 - RGBA.alpha; 
     RGB.red = Math.round((alpha * (RGBA.red/255) + ((1 - RGBA.alpha) * (bg.red/255))) * 255); 
     RGB.green = Math.round((alpha * (RGBA.green/255) + ((1 - RGBA.alpha) * (bg.green/255))) * 255); 
     RGB.blue = Math.round((alpha * (RGBA.blue/255) + ((1 - RGBA.alpha) * (bg.blue/255))) * 255); 

     document.write('<div style="display: block; width: 150px; height: 100px; background-color: ' + _toString(bg) + '">\ 
      <div style="color: #fff; width: 50px; height: 50px; background-color: ' + _toString(RGBA) + '"><small>RGBA<br>' + RGBA.alpha + '</small></div>\ 
      <div style="color: #fff; width: 50px; height: 50px; background-color: ' + _toString(RGB) + '"><small>RGB<br>' + RGBA.alpha + '</small></div>\ 
     </div>'); 

     // Increment alpha 
     RGBA.alpha += 0.25; 
    } 
    </script> 
</body> 
</html> 

die oben in beiden Chrome und Firefox führt zu erfolgreichen RGBA Running> RGB, wenn alpha 0,5, jede Abweichung weg von 0,5 führt zu einer Nichtübereinstimmung, sehr subtil, wenn die Die Abweichung ist sehr klein (dh es ist möglich, das Problem zu bemerken, wenn Alpha 0,55 ist).

Ich habe die Logik mehrmals umgeschrieben, die Logik vollständig in ihre grundlegendsten Teile erweitert, aber ich habe es versäumt, erfolgreich zu sein.

Antwort

7

Es sieht so aus, als ob Sie versuchen, die übliche Methode zum Mischen zu verwenden, aber die inkrementelle Schleife wirft mich ab. Gezogen von der OpenGL FAQ:

"Die oben beschriebene typische Verwendung [zum Blending] ändert die eingehende Farbe durch den zugehörigen Alpha-Wert und ändert die Zielfarbe um eins minus den eingehenden Alpha-Wert. Die Summe dieser beiden Farben ist dann in den Framebuffer zurückgeschrieben. "

Anstatt also eine while-Schleife verwenden:

alpha = 1 - RGBA.alpha; 
RGB.red = Math.round((RGBA.alpha * (RGBA.red/255) + (alpha * (bg.red/255))) * 255); 
RGB.green = Math.round((RGBA.alpha * (RGBA.green/255) + (alpha * (bg.green/255))) * 255); 
RGB.blue = Math.round((RGBA.alpha * (RGBA.blue/255) + (alpha * (bg.blue/255))) * 255); 
+0

Perfect! Ändere die Logik auf deine eigene (benutze das berechnete Alpha auf dem Hintergrund und nicht den Vordergrund), ich bekomme korrekte Werte für die verschiedenen Alphas, die durch die Schleife bestimmt werden! Bravo! – seeSaw