How to convert transparent colors to rgb - javascript

I have colors in following format
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
],
They are transparent colors, but when i convert them to this:
backgroundColor: [
getRandomColor(),
getRandomColor(),
],
They are not transparent anymore.
function getRandomColor() {
var letters = '0123456789ABCDEF';
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
Can anyone help me please thanks.

You should probably stick to the rgba format you originally used because you can't specify the alpha channel using the hex notation. So your code would have to go through another run just to convert it back from hex to rgba and add the alpha value.
See this example, it randomizes all four (rgba) components:
function getRandomColor() {
var color = [];
for (var i = 0; i < 3; i++ ) {
color.push(Math.floor(Math.random() * 256));
}
color.push(Math.random()); // alpha
return 'rgba(' + color.join(',') + ')';
}
div {text-align: center; margin: 20px 0; font-size: 40px;text-shadow: 0 0 1px #000; color: #ff0;cursor:pointer}
div:hover {text-shadow: 0 0 1px #000, 0 0 2px #000, 0 0 4px #000}
body {background: url(https://thumbs.dreamstime.com/x/retro-tile-background-5479386.jpg)}
<div onclick="this.style.background = getRandomColor()">Click me</div>
Of course, you can modify it to randomize only the RGB components and add alpha manually in case you want it locked at 0.2.

How to convert transparent colors to rgb?
here's a function that should work in converting rgba to rgb:
var backgroundColor = [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)'
]
function RGBfromRGBA(rgba) {
const [r, g, b, per] = rgba.match(/[0-9\.]+/g)
const diff = Number(per)
return `rgb(${ channelInter(Number(r),diff) },${channelInter(Number(g),diff) },${channelInter(Number(b),diff)})`
}
function channelInter(v, p) {
return 255 - (255 - v) * p | 0
}
var res = RGBfromRGBA(backgroundColor[1])
$('#rgba').css('background', backgroundColor[1]).html(backgroundColor[1])
$('#rgb').css('background', res).html(res)
div {
height: 100px;
width: 100px;
margin: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='rgba'></div>
<div id='rgb'></div>
in the snippet I also made a little test and it seems ok, let me know how it goes;

HEX (example): #42dff4 NOT transparent
RGB (example): rgb(100,42,230) NOT transparent
RGBA (example): rgba(123,42,243,0.5) Transparent
getRandomColor() returns colors in HEX value. HEX values are always non-transparent. If you want random rgba color values (transparent) do this:
function getRandomColor() {
return "rgba(" + Math.floor(Math.random() * 255) + ","
+ Math.floor(Math.random() * 255) + ","
+ Math.floor(Math.random() * 255) + ",0.2)";
}
This will return a rgba value, this is the code you are looking for.

You just have to return 3 different value for red, green, blue between 0 and 255....
edit : And use rgba, for specify the opacity of the color.
rgba(red,green,blue,alpha=opacity).
function getRndColor()
{
return "rgba("+Math.floor(Math.random()*255)+","+Math.floor(Math.random()*255)+","+Math.floor(Math.random()*255)+",0.2)";
}
console.log(getRndColor());

Related

Is there a faster way to render the Mandelbrot set for an animation?

I'm trying to code the Mandelbrot set as a fun project. I did it on my own, so it probably isn't optimized very well. I have a few questions about how to make my code better and how to add certain things to it. I used the library p5js, but that probably doesn't matter. (My code is at the bottom.)
First of all, when I render the set, the edges are very sharp. For example: See how the edges are sharp, because it operates pixel by pixel. However, I see in, for example, the Wikipedia page that it is possible to blend pixels and give more detail to the picture. How might I go about doing this? I've thought about calculating four values for each pixel, and blending them, but I feel like there should be another way.
Secondly, rendering the set takes much longer than it can if I want to animate it. I have to iterate more and more the more I zoom, so each frame would end up taking entire minutes to render. However, then I see videos like this https://www.youtube.com/watch?v=LhOSM6uCWxk or this https://www.youtube.com/watch?v=b005iHf8Z3g and I'd like to know how they are able to render these in less than a century. Is there an optimization method that I'm missing out on?
Another thing about the videos is how they are colored. For example, the first video I showed seemed like the colors were moving around everywhere, instead of staying in a constant spot, like the second video. What is the coloring method?
I've tried making the iterations low, but then I lose quality. I've tried an array of colors, but then it looks flat, like the second video. I want to know what's going on that I'm missing. I've looked at other solutions and seen that some people are rendering one pixel at a time, and that's what is making it slow. I do rows at a time for speed. All in all, what should I change to animate a set that looks pretty cool?
Finally, is there anything else that I should know to make my Mandelbrot set look amazing? Is there a completely different method for rendering that I should know? How is the first video made to look 3D? All of these clarifications would be nice to know.
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/addons/p5.sound.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.3.0/math.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<main>
</main>
<script src="sketch.js"></script>
</body>
</html>
//noprotect
var y = 0;
var ratio;
var xstart = -2;
var xend = 2;
var ystart = -2;
var yend = 2;
var maxiter = 100;
var _xstart;
var _xend;
const colors = [
"rgb(255, 0, 255)",
"rgb(255, 0, 127)",
"rgb(255, 0, 0)",
"rgb(255, 127, 0)",
"rgb(255, 255, 0)",
"rgb(127, 255, 0)",
"rgb(0, 255, 0)",
"rgb(0, 255, 127)",
"rgb(0, 255, 255)",
"rgb(0, 127, 255)",
"rgb(0, 0, 255)",
"rgb(127, 0, 255)"
];
function setup() {
noStroke();
createCanvas(window.innerWidth, window.innerHeight);
ratio = width/height;
background(0);
_xstart = xstart * (width/height);
_xend = xend * (width/height);
_xstart = (xstart + xend)/2 + xstart*(width/height);
_xend = (xstart+xend)/2 + xend*(width/height);
}
function mandelbrot(rconst, iconst) {
var iter = math.complex(0, 0);
var current = 0;
for(var i = 0; i < maxiter; i ++) {
iter = iter.pow(2);
iter = iter.add(rconst, iconst);
current ++;
if(sqrt(pow(iter.re, 2)+pow(iter.im, 2)) > 2) {
break;
}
}
if(current === maxiter) {
return(0);
} else {
//color array
return(colors[(current) % colors.length]);
//purple
var temp = floor(map(current, 0, maxiter/3, 0, 255));
if(temp > 255) {
temp = 255;
}
// return('rgb(' + temp + ', 0, ' + temp + ')')
//black and white
// return(map(current, 0, 30, 0, 255))
return('rgb(0, 0, ' + temp + ')')
}
}
function draw() {
if(y < height+1) {
for(var x = 0; x < width+1; x ++) {
fill(mandelbrot(map(x, 0, width, _xstart, _xend), map(y, 0, height, ystart, yend)))
rect(x, y, 1, 1);
}
y++;
}
fill(0);
rect(0, 0, 300, 15);
fill(255);
text("x: " + map(mouseX, 0, width, _xstart, _xend) + ", y: " + map(mouseY, 0, height, ystart, yend), 0, 10);
}

Javascript is not working for a color game

I have made a color game app but my javascript is not working fine and always alerts me with wrong. Please help me rectify this code. Thanks
var colors = [
"rgb(255,0,0)",
"rgb(255,255,0)",
"rgb(0,255,0)",
"rgb(0,255,255)",
"rgb(0,0,255)",
"rgb(255,0,255)"
]
var squares = document.querySelectorAll(".square");
var pickedColor = colors[3];
var colorDisplay = document.getElementById("colorDisplay");
colorDisplay.textContent = pickedColor;
for (var i = 0; i < squares.length; i++){
// add initial color to square
squares[i].style.background = colors[i];
// add click listeners to squares
squares[i].addEventListener("click", function(){
var clickedColor = this.style.background;
if(clickedColor == pickedColor){
alert("CORRECT");
} else {
alert("WRONG");
}
});
}
It always alerts "Wrong" and can't pick the right one.
When you apply style on element, style is normalized. RGB color is normalized with adding of spaces after commas. You need to added spaces to your array.
var colors = [
"rgb(255, 0, 0)",
"rgb(255, 255, 0)",
"rgb(0, 255, 0)",
"rgb(0, 255, 255)",
"rgb(0, 0, 255)",
"rgb(255, 0, 255)"
]
P.S. Here's my advice - learn how to debug using dev tools. Otherwise you'll face difficulties trying to develop something more sophisticated.
As #timbset outlined, "rgb(0, 255, 255)" is not equal to "rgb(0,255,255)".
Below is an excerpt from a fiddle that uses a function to compare the R, G and B values directly instead of comparing the entire RGB string (that may or may not be normalized).
if (compareColors(clickedColor, pickedColor)) {
alert("CORRECT");
} else {
alert("WRONG");
}
...
function compareColors (a, b) {
return (
getRGBfromString(a)[0] === getRGBfromString(b)[0] &&
getRGBfromString(a)[1] === getRGBfromString(b)[1] &&
getRGBfromString(a)[2] === getRGBfromString(b)[2]
)
}
function getRGBfromString (rgb) {
return rgb.substring(4, rgb.length - 1).replace(/ /g, '').split(',')
}
https://jsfiddle.net/mue1wfdm/

Convert dominant color with selected color

After working/studying hours with canvas i have managed to get the image clone and it's pixels now i have made the user select a color from a color specterm and i have that color hex in my function :
move: function (color) {
// 'color' is the value user selected
var img_id = jQuery(".selected_bg_img").attr("id");
alert(img_id);
var x = 0;
var y = 0;
var width = 409;
var height = 409;
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById(img_id);
ctx.drawImage(img,x,y,width,height);
var imageData = ctx.getImageData(0,0,width,height);
var data = imageData.data;
alert(data);
}
now two tasks are getting in way,
1. How do we extract the maximum color from data ?
2. How do we convert that maximum color to the color we got in function ?
for live working example i have link given at end
NOTE: Select the images (any last 3) from left side of the product image and and when color is choose it clones the image to the canvas below.
Here i am trying to clone the image with replacement of maximum color with the color user selected.
NOTE: Maximum color i mean (dominant color in image), e.g http://lokeshdhakar.com/projects/color-thief/ this project is getting the dominant color of image but it's on node and i'm trying to get the dominant and to change that color before cloning too .
for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
*****EDIT*****
My problem is not very complex i think i have this image
so we can see clearly that the dominant color is grey, by any method i am just trying to replace that color with the new color i have in my function move and draw that image with the new color. The image from where i have taken and shows another example :
http://www.art.com/products/p14499522-sa-i3061806/pela-silverman-colorful-season-i.htm?sOrig=CAT&sOrigID=0&dimVals=729271&ui=573414C032AA44A693A641C8164EB595
on left side of image when we select the similar image they have option "change color" at the bottom center of image. This is what exactly i'm trying to do.
So now i tried to read the image 1x1 and this is what i get in the console when i log it(particular for the image i have shown) :
[166, 158, 152, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…]
So it maybe the very first start from top left corner, i guess it need to be iterated over whole image and this is what i get when i iterated over whole image:
[110, 118, 124, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255…]
The loop i used for iteration is:
var imageData = ctx.getImageData(0,0,width,height);
var data = imageData.data;
for (var i=0;i<data.length;i+=4)
{
data[i]=255-data[i];
data[i+1]=255-data[i+1];
data[i+2]=255-data[i+2];
data[i+3]=255;
}
console.log(data);
Is this iteration right ? If yes, it seems to be now matter of replacing the dominant color and i'm blank here how do we replace it and write back image with the replaced color or is there something more ?
*************EDIT***********
i have now user value in rgb, need to look for places where that value should be placed
This answer may be what you want as it is a little unclear.
Finding the dominant colour in an image
There are two ways that I use. There are many other ways to do it, which is the best is dependent on the needs and quality requiered. I will concentrat on using a histogram to filter out irrelevent pixels to get a result.
The easy way.
Create a canvas that is 1 by 1 pixel. Ensure that canvas smoothing is on.
ctx.imageSmoothingEnabled = true;
ctx.mozImageSmoothingEnabled = true;
The draw the image onto that 1 by 1 canvas
ctx.drawImage(image,0,0,1,1);
Get the pixel data
var data = ctx.getImageData(0,0,1,1);
And the rgb values are what you are after.
r = data.data[0];
g = data.data[0];
b = data.data[0];
The result applied to the image below.
The long way
This method is long and problematic. You need to ignore the low and high values in the histogram for rgb (ignore black and white values) and for HSL ignore Saturations and Values (Lightness) that are 0 or 100% or you will get reds always dominating for images that have good contrast.
In image processing a histogram is a plot of the distribution of image properties (eg red green blue) within the image. As digital images have discrete values the histogram (a bar graph) will plot along the x axis the value and in the y axis the number of pixels that have that value.
An example of the histogram. Note that this code will not run here as there is cross origin restriction. (sorry forgot my browser had that disabled).
/** CopyImage.js begin **/
// copies an image adding the 2d context
function copyImage(img){
var image = document.createElement("canvas");
image.width = img.width;
image.height = img.height;
image.ctx = image.getContext("2d");
image.ctx.drawImage(img, 0, 0);
return image;
}
function copyImageScale(img,scale){
var image = document.createElement("canvas");
image.width = Math.floor(img.width * scale);
image.height = Math.floor(img.height * scale);
image.ctx = image.getContext("2d");
image.ctx.drawImage(img, 0, 0,image.width,image.height);
return image;
}
/** CopyImage.js end **/
function getHistogram(img){ // create a histogram of rgb and Black and White
var R,G,B,BW;
R = [];
G = [];
B = [];
BW = []; // Black and white is just a mean of RGB
for(var i=0; i < 256; i++){
R[i] = 0;
G[i] = 0;
B[i] = 0;
BW[i] = 0;
}
var max = 0; // to normalise the values need max
var maxBW = 0; // Black and White will have much higher values so normalise seperatly
var data = img.ctx.getImageData(0,0,img.width,img.height);
var d = data.data;
var r,g,b;
i = 0;
while(i < d.length){
r = d[i++]; // get pixel rgb values
g = d[i++];
b = d[i++];
i++; // skip alpha
R[r] += 1; // count each value
G[g] += 1;
B[b] += 1;
BW[Math.floor((r+g+b)/3)] += 1;
}
// get max
for(i = 0; i < 256; i++){
max = Math.max(R[i],G[i],B[i],max);
maxBW = Math.max(BW[i],maxBW);
}
// return the data
return {
red : R,
green : G,
blue : B,
gray : BW,
rgbMax : max,
grayMax : maxBW,
};
}
function plotHistogram(data,ctx,sel){
var w = ctx.canvas.width;
var h = ctx.canvas.height;
ctx.clearRect(0,0,w,h); // clear any existing data
var d = data[sel];
if(sel !== "gray"){
ctx.fillStyle = sel;
}
var rw = 1 / d.length; // normalise bar width
rw *= w; // scale to draw area;
for(var i = 0; i < d.length; i++ ){
var v = 1-(d[i]/data.rgbMax); // normalise and invert for plot
v *= h; // scale to draw area;
var x = i/d.length; // normaise x axis
x *= w; // scale to draw area
if(sel === 'gray'){
ctx.fillStyle = "rgb("+i+","+i+","+i+")";
}
ctx.fillRect(x,v,rw,h-v); // plot the bar
}
}
var canMain = document.createElement("canvas");
canMain.width = 512;
canMain.height = 512;
canMain.ctx = canMain.getContext("2d");
document.body.appendChild(canMain);
var ctx = canMain.ctx;
var can = document.createElement("canvas");
can.width = 512;
can.height = 512;
can.ctx = can.getContext("2d");
// load image and display histogram
var image = new Image();
image.src = "http://i.stack.imgur.com/tjTTJ.jpg";
image.onload = function(){
image = copyImage(this);
var hist = getHistogram(image);
// make background black
ctx.fillStyle = "black"
ctx.fillRect(0,0,ctx.canvas.width,ctx.canvas.height);
// create and show each plot
plotHistogram(hist,can.ctx,"red");
document.body.appendChild(copyImageScale(can,0.5));
ctx.drawImage(can,0,0,canvas.width,canvas.height);
plotHistogram(hist,can.ctx,"green");
document.body.appendChild(copyImageScale(can,0.5));
ctx.globalCompositeOperation = "lighter"
ctx.drawImage(can,0,0,canvas.width,canvas.height);
plotHistogram(hist,can.ctx,"blue");
document.body.appendChild(copyImageScale(can,0.5));
ctx.globalCompositeOperation = "lighter"
ctx.drawImage(can,0,0,canvas.width,canvas.height);
plotHistogram(hist,can.ctx,"gray");
document.body.appendChild(copyImageScale(can,0.5));
ctx.globalCompositeOperation = "source-over"
ctx.globalAlpha = 0.9;
ctx.drawImage(can,0,0,canvas.width,canvas.height);
ctx.globalAlpha = 1;
}
As the above code required a hosted image the results are shown below.
The image
The RGB and gray histograms as output from above code.
From this you can see the dominant channels and the distribution of rgb over the image (Please note that I removed the black as this image has a lot of black pixels that where make the rest of the pixel counts shrink into insignificance)
To find the dominant colour you can do the same but for the HSL values. For this you will need to convert from RGB to HSL. This answer has a function to do that. Then it is just a matter of counting each HSL value and creating a histogram.
The next image is a histogram in HSL of the above sample image.
As you can see there is a lot of red, then a peek at yellow, and another in green.
But as is this still will not get you what you want. The second histogram (saturation) shows a clear peak in the center. There are a lot of colours that have good saturation but this does not tell you what colour that is.
You need to filter the HSL value to around that peak.
What I do is multiply the HSL values by the f(s) = 1-Math.abs(s-50)/50 s is Saturation range 0-100. This will amplify hue and value where saturation is max. The resulting histogram looks like
Now the peak hue (ignoring the reds) is orange. The hue value is ~ 42. Then you apply a filter that removes all pixels that are not near the hue = 42 (you may want to give a falloff). You apply this filter on the HSL value you get after the last step. The next image shows the resulting image after applying this filter to the original
and then get a sum of all the remaining pixel's R,G,B. The mean of each RGB value is the common colour.
The common colour as by this method.
Note the result is different than if you apply this method as described and in the code above. I used my own image processing app to get the instrume steps and it uses true logarithmic photon counts for RGB values that will tend to be darker than linear interpolation. The final step expands the filtered pixel image to an instrume step that is too complicated to describe here (a modification on the easy method at start of answer). looks like
Also I applied this to the whole image, this can be very slow for large images, but it will work just as well if you first reduce the size of the image (must have image smoothing on (defaults of most browsers)). 128 8 128 is a good size but you can go down lower. It will depend on the image how small you can make it befor it fails.

How do you get random RGB in Javascript? [duplicate]

This question already has answers here:
Random color generator
(64 answers)
Closed 8 years ago.
I have this code that uses RGB color selection and I was wondering how to make JavaScript do a random color using the RGB method and remember it throughout the code.
EDIT: I tried this:
var RGBColor1 = (Math.round, Math.random, 255)
var RGBColor2 = (Math.round, Math.random, 255)
var RGBColor3 = (Math.round, Math.random, 255)
but it doesn't work. Help please!
EDIT 2: The code uses this:
g.fillStyle="rgba(R,G,B,0.2)";
g.strokeStyle="rgba(R,G,B,0.3)";
E();
The letters represent the color of RGB.
EDIT 3: The doubles of this question are using HEX values, not RGB values.
function random_rgba() {
var o = Math.round, r = Math.random, s = 255;
return 'rgba(' + o(r()*s) + ',' + o(r()*s) + ',' + o(r()*s) + ',' + r().toFixed(1) + ')';
}
var color = random_rgba();
g.fillStyle = color;
g.strokeStyle = color;
FIDDLE
const randomBetween = (min, max) => min + Math.floor(Math.random() * (max - min + 1));
const r = randomBetween(0, 255);
const g = randomBetween(0, 255);
const b = randomBetween(0, 255);
const rgb = `rgb(${r},${g},${b})`; // Collect all to a css color string
Here's a very simple method that works off of a single random number generation. Basically, it generates a number between 0 and 0xfffff (or 2^24, the highest number you can get from 24 bits). The highest value you can get from 8 bits is 255. This algorithm takes the left-most 8 bits of the random number for RED, the middle 8 bits for GREEN, and the last 8 bits for BLUE, using all 24 bits of the random number.
function getRandomRgb() {
var num = Math.round(0xffffff * Math.random());
var r = num >> 16;
var g = num >> 8 & 255;
var b = num & 255;
return 'rgb(' + r + ', ' + g + ', ' + b + ')';
}
for (var i = 0; i < 10; i++) {
console.log(getRandomRgb());
}
Console output (sample):
rgb(2, 71, 181)
rgb(193, 253, 111)
rgb(172, 127, 203)
rgb(203, 53, 175)
rgb(226, 45, 44)
rgb(102, 181, 19)
rgb(92, 165, 221)
rgb(250, 40, 162)
rgb(250, 252, 120)
rgb(67, 59, 246)
Adapted from source.

Convert RGBA to RGB taking background into consideration [duplicate]

This question already has answers here:
Closed 10 years ago.
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.
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);

Categories

Resources