Increase or decrease color saturation

I would like to know an algorithm to increase or decrease one RGB color saturation

for example, if I have rgb(200, 30, 40) color rgb(200, 30, 40) (red), then the function stub will be

 function Saturation(color, factor) where color.r = 200, color.g= 30 and color.b=40 

Does anyone know a library or has a piece of code that does this?

+6
source share
3 answers

The following Bali Balo sentence 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 HSV format (hue, saturation, and value) you can manually change the S component in this way:

 var hsv= RGBtoHSV ([200,100,100]); alert(hsv) hsv[1] *= 1.5; alert(hsv) var rgb= HSVtoRGB(hsv); alert(rgb); //new color 
+9
source

Here's a quick and dirty way, which probably doesn't match any technical way, but involves less computation than converting to HSV and vice versa (so it does it faster if that matters):

Grayscale is the equivalent of calculating the luminosity averaged over a portion of an RGB pixel. We can mix grayness by applying a value weighted to the gray part, compared to the color 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 pick it up and add the corresponding color 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, the disclaimer that it “looks” saturated, but probably in no way matches the technical definition of “saturation” (whatever that is); I just posted it in the hope that it would help passers-by.

+4
source

// My solution is for colors in the HEX format. You can request saturation for percent.

 function applySaturationToHexColor(hex, saturationPercent) { if (!/^#([0-9a-f]{6})$/i.test(hex)) { throw('Unexpected color format'); } if (saturationPercent < 0 || saturationPercent > 100) { throw('Unexpected color format'); } var saturationFloat = saturationPercent / 100, rgbIntensityFloat = [ parseInt(hex.substr(1,2), 16) / 255, parseInt(hex.substr(3,2), 16) / 255, parseInt(hex.substr(5,2), 16) / 255 ]; var rgbIntensityFloatSorted = rgbIntensityFloat.slice(0).sort(function(a, b){ return a - b; }), maxIntensityFloat = rgbIntensityFloatSorted[2], mediumIntensityFloat = rgbIntensityFloatSorted[1], minIntensityFloat = rgbIntensityFloatSorted[0]; if (maxIntensityFloat == minIntensityFloat) { // All colors have same intensity, which means // the original color is gray, so we can't change saturation. return hex; } // New color max intensity wont change. Lets find medium and weak intensities. var newMediumIntensityFloat, newMinIntensityFloat = maxIntensityFloat * (1 - saturationFloat); if (mediumIntensityFloat == minIntensityFloat) { // Weak colors have equal intensity. newMediumIntensityFloat = newMinIntensityFloat; } else { // Calculate medium intensity with respect to original intensity proportion. var intensityProportion = (maxIntensityFloat - mediumIntensityFloat) / (mediumIntensityFloat - minIntensityFloat); newMediumIntensityFloat = (intensityProportion * newMinIntensityFloat + maxIntensityFloat) / (intensityProportion + 1); } var newRgbIntensityFloat = [], newRgbIntensityFloatSorted = [newMinIntensityFloat, newMediumIntensityFloat, maxIntensityFloat]; // We've found new intensities, but we have then sorted from min to max. // Now we have to restore original order. rgbIntensityFloat.forEach(function(originalRgb) { var rgbSortedIndex = rgbIntensityFloatSorted.indexOf(originalRgb); newRgbIntensityFloat.push(newRgbIntensityFloatSorted[rgbSortedIndex]); }); var floatToHex = function(val) { return ('0' + Math.round(val * 255).toString(16)).substr(-2); }, rgb2hex = function(rgb) { return '#' + floatToHex(rgb[0]) + floatToHex(rgb[1]) + floatToHex(rgb[2]); }; var newHex = rgb2hex(newRgbIntensityFloat); return newHex; } 
+1
source

All Articles