I would like to know the algorithm to increase or decrease one RGB color saturation
for example if I have the color rgb(200, 30, 40)
(red) the function stub would be
function Saturation(color, factor)
where color.r = 200, color.g= 30 and color.b=40
Anyone knows a library or has a code snippet that does that?
To adjust saturation, add a Hue/Saturation adjustment layer. Then click and drag the Saturation slider in the Properties panel to increase or decrease the saturation.
The higher the saturation of a color, the more vivid it is. The lower the saturation of a color, the closer it is to gray. Lowering the saturation of a photo can have a “muting” or calming effect, while increasing it can increase the feel of the vividness of the scene.
There are four different ways to lower the saturation of a pure colour. You can either add grey, add white, add black, or dilute a pure colour using its complementary colour.
The higher the saturation of a color, the more vivid and intense it is. The lower a color's saturation, the closer it is to pure gray on the grayscale.
Following Bali Balo suggestion I came up with:
RGBtoHSV= function(color) {
var r,g,b,h,s,v;
r= color[0];
g= color[1];
b= color[2];
min = Math.min( r, g, b );
max = Math.max( r, g, b );
v = max;
delta = max - min;
if( max != 0 )
s = delta / max; // s
else {
// r = g = b = 0 // s = 0, v is undefined
s = 0;
h = -1;
return [h, s, undefined];
}
if( r === max )
h = ( g - b ) / delta; // between yellow & magenta
else if( g === max )
h = 2 + ( b - r ) / delta; // between cyan & yellow
else
h = 4 + ( r - g ) / delta; // between magenta & cyan
h *= 60; // degrees
if( h < 0 )
h += 360;
if ( isNaN(h) )
h = 0;
return [h,s,v];
};
HSVtoRGB= function(color) {
var i;
var h,s,v,r,g,b;
h= color[0];
s= color[1];
v= color[2];
if(s === 0 ) {
// achromatic (grey)
r = g = b = v;
return [r,g,b];
}
h /= 60; // sector 0 to 5
i = Math.floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i ) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default: // case 5:
r = v;
g = p;
b = q;
break;
}
return [r,g,b];
}
by converting to the HSV (hue, saturation and value) format you can manually change the S component in this manner:
var hsv= RGBtoHSV ([200,100,100]);
alert(hsv)
hsv[1] *= 1.5;
alert(hsv)
var rgb= HSVtoRGB(hsv);
alert(rgb); //new color
Here's a quick and dirty way that probably isn't correct in any technical way, but involves less computation than converting to HSV and back (so renders quicker if that matters):
Grayscale is the equivalent of calculating luminosity averaged over the RGB parts of the pixel. We can mix grayness by applying a value weighting to the gray part versus the colored part:
var pixels = context.getImageData(0, 0, canvas.width, canvas.height);
grayscale = function (pixels, value) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
var gray = 0.2989*r + 0.5870*g + 0.1140*b; //weights from CCIR 601 spec
d[i] = gray * value + d[i] * (1-value);
d[i+1] = gray * value + d[i+1] * (1-value);
d[i+2] = gray * value + d[i+2] * (1-value);
}
return pixels;
};
So instead of adding "grayness", we can take it away and add the relevant color back in to "saturate":
saturate = function (pixels, value) {
var d = pixels.data;
for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
var gray = 0.2989*r + 0.5870*g + 0.1140*b; //weights from CCIR 601 spec
d[i] = -gray * value + d[i] * (1+value);
d[i+1] = -gray * value + d[i+1] * (1+value);
d[i+2] = -gray * value + d[i+2] * (1+value);
//normalize over- and under-saturated values
if(d[i] > 255) d[i] = 255;
if(d[i+1] > 255) d[i] = 255;
if(d[i+2] > 255) d[i] = 255;
if(d[i] < 0) d[i] = 0;
if(d[i+1] < 0) d[i] = 0;
if(d[i+2] < 0) d[i] = 0;
}
return pixels;
};
Again, disclaimer that this "looks" saturated but probably in no way adheres to the technical definition of "saturation" (whatever that is); I've simply posted this in the hope that it's helpful to passers-by.
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