Possible Duplicate:
Convert RGBA color to RGB
I'm trying to convert a RGBA color, with a alpha < 1 into a solid RGB representation taking into account the background color.
Using the algorithm provided at this question I manage to get correct conversion to a solid RGB color - BUT ONLY when alpha = 0.5.
Here's my test code:
<!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 the above in both Chrome and Firefox results in successful RGBA->RGB when alpha is 0.5, any deviation away from 0.5 results in a mismatch, very subtle if the deviation is very small (i.e. it's possible to notice the issue when alpha is 0.55).
I've rewritten the logic several times, fully expanding the logic into its most basic parts but I've failed to be successful.
An RGB color value represents RED, GREEN, and BLUE light sources. An RGBA color value is an extension of RGB with an Alpha channel (opacity).
It looks like you're trying to use the common method for blending, but the incremental loop is throwing me off. Pulled from the OpenGL FAQ:
"The typical use described above [for blending] modifies the incoming color by its associated alpha value and modifies the destination color by one minus the incoming alpha value. The sum of these two colors is then written back into the framebuffer."
So instead of a while loop, use:
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With