2012-07-23 12 views
6

Powiel możliwe:
Convert RGBA color to RGBKonwersja RGB do RGBA biorąc pod uwagę tło

próbuję przekonwertować kolor RGBA, z alfa < 1 do stałej reprezentacji RGB biorąc pod uwagę kolor tła.

Korzystanie z algorytmu pod adresem this question Udało mi się uzyskać poprawną konwersję na stały kolor RGB - ALE TYLKO gdy alpha = 0,5.

Oto mój kodu testu:

<!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> 

Running wyżej w obu wyników Chrome i Firefoksa w udanym RGBA-> RGB gdy alfa 0.5, każde odchylenie od 0,5 daje w wyniku niedopasowania, bardzo subtelny, jeśli odchylenie jest bardzo małe (tzn. można zauważyć problem, gdy alfa wynosi 0,55).

Wielokrotnie przepisałem tę logikę, całkowicie rozszerzając logikę na jej najbardziej podstawowe części, ale nie udało mi się osiągnąć sukcesu.

Odpowiedz

7

Wygląda na to, że próbujesz użyć typowej metody mieszania, ale pętla przyrostowa mnie wyrzuca. Wyciągnięty z FAQ OpenGL:

"Typowe zastosowanie opisane powyżej [do mieszania] modyfikuje kolor przychodzący przez skojarzoną z nim wartość alfa i modyfikuje kolor docelowy o jeden minus wartość przychodzącej alfa. Suma tych dwóch kolorów jest wtedy zapisany z powrotem do bufora ramki. "

Więc zamiast pętli while, zastosowanie:

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! Zmieniono logikę na własną (używając obliczonej alfa na tle, a nie na pierwszym planie), otrzymuję poprawne wartości dla różnych alphas ustalonych przez pętlę! Brawo! – seeSaw

Powiązane problemy