How can we convert CMYK to RGB in illustrator script? - javascript

I fetch cmyk value for color and convert it into RGB and this RGB color is displayed in an html extension. But Color picker shows different values for RGB color due to which we get difference in color shades.i use normal java script method to convert CMYK to RGB.
Following formula that i used to convert CMYK to RGB--
CMYK to CMY
C = 1 - ( R / 255 )
M = 1 - ( G / 255 )
Y = 1 - ( B / 255 )
and then CMY TO RGB
R = ( 1 - C ) * 255
G = ( 1 - M ) * 255
B = ( 1 - Y ) * 255
Color picker shows different color as calculated from normal functions.
For eg : Color is Red.
In general
RGB : 255,0,0
CMYK : 0%,100%,100%,0%
HEXCODE : #FF0000
but in illustrator on double click of color picker it shows as
RGB : 237,28,36
CMYK : 0%,100%,100%,0%
HEXCODE : #ED1C24
So, is there any method or formula which can get the same values as calculated from the color picker .
Please Help ,thanks in advance.
please find attached image link for reference.
http://screencast.com/t/sYa1Y301Qa2

In Illustrator scripting you will find use in the app.convertSampleColor() function.
This function takes in the source and destination space names as well as an array of color values and returns an illustrator-accurate converted color array in the destination space.

CMYK to RGB conversion:
The R,G,B values are given in the range of 0-255.
The red (R) color is calculated from the cyan (C) and black (K) colors:
R = 255 × (1-C) × (1-K)
The green color (G) is calculated from the magenta (M) and black (K) colors:
G = 255 × (1-M) × (1-K)
The blue color (B) is calculated from the yellow (Y) and black (K) colors:
B = 255 × (1-Y) × (1-K)

There is no simple or a general conversion formula for RGB to CMYK. Basically, RGB is about present of optical color, while CMYK is about present of ink color. When you increase R, G and B you get brighter color, while in general CMYK acts opposite. I think these two articles can help you understand them in depth: Adobe RGB and Color space
The problem is that if you want to have exact values as softwares like illustrator or photoshop, you need to use ICC profile which is not accessible inside javascript (see this question: Is there any client-side technology able to convert sRGB to CMYK through an ICC color profile?).
However there are some mathematical conversions like just you did, or this python version, which converts the CMYK to CMY then to RGB (they are not standard ICC colors):
C = C * (1.0 - K) + K
M = M * (1.0 - K) + K
Y = Y * (1.0 - K) + K
R = 255 * (1.0 - C)
G = 255 * (1.0 - M)
B = 255 * (1.0 - Y)

PLEASE EXCUSE ME IN MY BAD ENGLISH !!
I THINK THAT I FIGURED IT OUT
THE PROBLEM IS THAT CMYK CYAN RETURNS TO LIGHT-CYAN IN RGB
AND ALSO CMYK PINK RETURNS TO REAL-BLUE IN RGB
SO I ADDED SOME VALUES :
IF CYAN > MAGENTA .. WE ADD 25% OF CYAN VALUE TO MAGENTA VALUE
ELSE IF CYAN < MAGENTA .. WE CUT 50% OF CYAN VALUE TO SHOW REAL-PINK
IT WORKED FOR ME AND HERE IS THE EXTENDSCRIPT CODE :
function CMYKTORGB1(_c, _m, _y, _k) {
var C = _c / 100; // THE PROBLEM THAT IT RETURNS LIGHT-CYAN IN RGB
var M = _m / 100;
var Y = _y / 100;
var K = _k / 100;
var _mc = 0;
if (_c > 0) {
if (_m >= _c) {
_mc = _c / 2;
C = (_c - _mc) / 100; // THIS WILL FIX BLUE-PINK VALUE
}
else {
_mc = _c / 4;
M = (_m + _mc) / 100; // THIS WILL FIX LIGHT-CYAN VALUE
}
}
var R = 255 * (1 - C) * (1 - K);
var G = 255 * (1 - M) * (1 - K);
var B = 255 * (1 - Y) * (1 - K);
if (R < 0) { R = 0; }
if (G < 0) { G = 0; }
if (B < 0) { B = 0; }
return [R, G, B];
}
OR THIS FUNTION IT WORKING TOO :
function CMYKTORGB2(_c, _m, _y, _k) {
var C = _c / 100; // THE PROBLEM THAT IT RETURNS LIGHT-CYAN IN RGB
var M = _m / 100;
var Y = _y / 100;
var K = _k / 100;
var _mc = 0;
if (_c > 0) {
if (_m >= _c) {
_mc = _c / 2;
C = (_c - _mc) / 100; // THIS WILL FIX BLUE-PINK VALUE
}
else {
_mc = _c / 4;
M = (_m + _mc) / 100; // THIS WILL FIX LIGHT-CYAN VALUE
}
}
var _C = C * (1.0 - K) + K
var _M = M * (1.0 - K) + K
var _Y = Y * (1.0 - K) + K
var R = 255 * (1.0 - C)
var G = 255 * (1.0 - M)
var B = 255 * (1.0 - Y)
if (R < 0) { R = 0; }
if (G < 0) { G = 0; }
if (B < 0) { B = 0; }
return [R, G, B];
}

Related

Methodology to convert RGB to Wavelength

I want to convert the RGB image matrix to corresponding Wavelenth matrix. If there any methodology or alogorithm just mention here.
Looking at other answers you could do two-step process:
Convert RGB to HSV colour model (see How to get the wavelength of a pixel using RGB?)
Convert Hue value to wavelength (see Hue to wavelength mapping)
Converting from RGB to HSV
function [h,s,v] = rgb2hsv(r, g, b)
MAX_PIXEL_VALUE = 255.0;
assert_checktrue ( r <= MAX_PIXEL_VALUE )
assert_checktrue ( g <= MAX_PIXEL_VALUE )
assert_checktrue ( b <= MAX_PIXEL_VALUE )
r = r / MAX_PIXEL_VALUE;
g = g / MAX_PIXEL_VALUE;
b = b / MAX_PIXEL_VALUE;
max_val = max(r, g, b);
min_val = min(r, g, b);
v = max_val;
if max_val == 0.0 then
s = 0;
h = 0;
elseif (max_val - min_val) == 0.0 then
s = 0;
h = 0;
else
s = (max_val - min_val) / max_val;
if max_val == r then
h = 60 * ((g - b) / (max_val - min_val)) + 0;
elseif max_val == g then
h = 60 * ((b - r) / (max_val - min_val)) + 120;
else
h = 60 * ((r - g) / (max_val - min_val)) + 240;
end
end
if h < 0 then
h = h + 360.0;
end
h = h / 2;
s = s * MAX_PIXEL_VALUE;
v = v * MAX_PIXEL_VALUE;
return [h, s, v]
endfunction
Converting from Hue to wavelength
function wavelength = hue2wavelength(hue)
// There is nothing corresponding to magenta in the light spectrum,
// So let's assume that we only use hue values between 0 and 270.
assert_checktrue(hue >= 0);
assert_checktrue(hue <= 270);
// Estimating that the usable part of the visible spectrum is 450-620nm,
// with wavelength (in nm) and hue value (in degrees), you can improvise this:
wavelength = 620 - 170 / 270 * hue;
endfunction
Putting it together
function wavelength = rgb2wavelength(r,g,b)
[h,s,v] = rgb2hsv(r,g,b);
wavelength = hue2wavelength(h);
endfunction

How to Use HSL to RGB Conversion Function

Feel like I'm missing something really simple here, but I can't get the formula posted from an answer from HSL to RGB color conversion to work. The function in question is:
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
My issue, I believe, is in regard to what to enter as my 'h' parameter. Typically, when using HSL in CSS or Photoshop, the hue value is a number between 0 and 360, but this function calls for a value in between 0 and 1. Can someone explain to me how I would, for example, convert a hue value of 240 to the equivalent value between 0 and 1, so I can plug it into this formula? I tried dividing 240 by 360, but this did not work.
Looks like the original algorithm is wrong. According to wikipedia, you can get the chroma & lightness adjustments independent of hue (hence the similar b value), but anything else requires a little more math—specifically modulo. It doesn't look like that algorithm handles that particular conversion well, especially considering it expects hue to be in the range [0, 1]. Try this algorithm instead:
// expected hue range: [0, 360)
// expected saturation range: [0, 1]
// expected lightness range: [0, 1]
var hslToRgb = function(hue, saturation, lightness){
// based on algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB
if( hue == undefined ){
return [0, 0, 0];
}
var chroma = (1 - Math.abs((2 * lightness) - 1)) * saturation;
var huePrime = hue / 60;
var secondComponent = chroma * (1 - Math.abs((huePrime % 2) - 1));
huePrime = Math.floor(huePrime);
var red;
var green;
var blue;
if( huePrime === 0 ){
red = chroma;
green = secondComponent;
blue = 0;
}else if( huePrime === 1 ){
red = secondComponent;
green = chroma;
blue = 0;
}else if( huePrime === 2 ){
red = 0;
green = chroma;
blue = secondComponent;
}else if( huePrime === 3 ){
red = 0;
green = secondComponent;
blue = chroma;
}else if( huePrime === 4 ){
red = secondComponent;
green = 0;
blue = chroma;
}else if( huePrime === 5 ){
red = chroma;
green = 0;
blue = secondComponent;
}
var lightnessAdjustment = lightness - (chroma / 2);
red += lightnessAdjustment;
green += lightnessAdjustment;
blue += lightnessAdjustment;
return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];
};
It may fail on a few edge cases, but those should be easy fixes

shift rgb one color to another color of image HTML 5 canvas

I have a png Image for my game developing in HTML 5 and javascript. I want to give it different color. image have 4 different color. I want to shift every color to other.
For Example
Image have 4 color
1. brown
2.lite brown
3.dark brown
4. dark dark brown
I want to convert it in blue then it should be
1.blue
2.lite blue
3.dark blue
4.dark dark blue
I know how to change color in HTML5 canvas but have no idea how two relate
last three color with first one.
I have google for color transformation but nothing found helpful.
thanks.
To get best result you will have to change color space from RGB to HSL (or HSV). This allows you to work with Hue, Saturation and Luminance. With hue you can "rotate" your color into another.
You must then define the range of colors you want to change and shift the colors within this range to your target color, then convert the HSL value back to RGB (this is what for example Photoshop uses).
Image from WikiPedia (see link at bottom)
RGB to HSL -
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param Number h The hue
* #param Number s The saturation
* #param Number l The lightness
* #return Array The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [r * 255, g * 255, b * 255];
}
In HSL color space you can "rotate" the colors. All you need to do is to find the range by finding maximum and minimum angle, saturation and luminance levels of the colors you want to rotate. As this is HSL related colors will be close to each other so you can find the brown variations being in a short range (you could use a rectangle - or rather: a cube, to define the range. See my palette link below to get the idea).
Then you check each pixel if they have a HSL value within that range and if they do you adjust it and convert it back to RGB.
HSL to RGB -
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*/
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
I made this JavaScript palette picker in the past which uses these color models to get and set colors, and which you can study to see them in action. You can also use it to find the range you want to use for alteration (a good start point would of course be in the lower left corner).
You basically iterate through all your pixels, convert RGB to HSL/HSV, check if they are in your range, adjust if they are and convert the adjusted pixel back to RGB.
For more details go the articles mentioned in comment sections above of the functions:
http://en.wikipedia.org/wiki/HSL_color_space

Javascript - Sort rgb values

Using javascript/jquery, I want to sort an array of rgba values to the colours of the visible spectrum. By doing this, like shades should be bunched together. Is there a plugin to do this or how would I go about doing it?
Spectrum image: http://www.gamonline.com/catalog/colortheory/images/spectrum.gif
Disclosure: I'm the author of the library recommended below.
If you don't mind using a library, here's a much more concise version of Oriol's detailed response. It uses the sc-color library:
var sorted = colorArray.sort(function(colorA, colorB) {
return sc_color(colorA).hue() - sc_color(colorB).hue();
});
If your array of colors is like this:
var rgbArr = [c1, c2, c3, ...]
where each color ci is an array of three numbers between 0 and 255
ci = [red, green, blue]
then, you can use this function to convert the colors to HSL
function rgbToHsl(c) {
var r = c[0]/255, g = c[1]/255, b = c[2]/255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return new Array(h * 360, s * 100, l * 100);
}
and sort them by hue
var sortedRgbArr = rgbArr.map(function(c, i) {
// Convert to HSL and keep track of original indices
return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
// Sort by hue
return c1.color[0] - c2.color[0];
}).map(function(data) {
// Retrieve original RGB color
return rgbArr[data.index];
});
Here is a runnable example (thanks Ionică Bizău):
function display(container, arr) {
container = document.querySelector(container);
arr.forEach(function(c) {
var el = document.createElement("div");
el.style.backgroundColor = "rgb(" + c.join(", ") + ")";
container.appendChild(el);
})
}
function rgbToHsl(c) {
var r = c[0] / 255,
g = c[1] / 255,
b = c[2] / 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return new Array(h * 360, s * 100, l * 100);
}
var rgbArr = [];
for (var i = 0; i < 100; ++i) {
rgbArr.push([
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256),
Math.floor(Math.random() * 256)
]);
}
display("#before", rgbArr);
var sortedRgbArr = rgbArr.map(function(c, i) {
// Convert to HSL and keep track of original indices
return {color: rgbToHsl(c), index: i};
}).sort(function(c1, c2) {
// Sort by hue
return c1.color[0] - c2.color[0];
}).map(function(data) {
// Retrieve original RGB color
return rgbArr[data.index];
});
display("#after", sortedRgbArr);
#before > div,
#after > div {
width: 1%;
height: 20px;
display: inline-block;
}
Random colors: <div id="before"></div>
Same colors, sorted by hue: <div id="after"></div>
sortedRgbArr will contain the rgb colors of rgbArr sorted more or less like the colors of the visible spectrum.
The problem is that the HSL spectrum looks like this:
Your spectrum is weird because it doesn't have all colors, such as pink.
I guess that's because pink doesn't exist in the nature, it's a combination of the colors of the opposite extremes of light's spectrum. But we have it in rgb, so you have to decide where do you want it.
Moreover, it seems that your spectrum goes from lower to higher wavelength, not frequency. But then your spectrum is a reverse of HSL's spectrum.
Replace c1.color[0] - c2.color[0] with c2.color[0] - c1.color[0] if you want it like your spectrum.

JavaScript Calculate brighter colour

I have a colour value in JS as a string
#ff0000
How would I go about programatically calculating a brighter/lighter version of this colour, for example #ff4848, and be able to calculate the brightness via a percentage, e.g.
increase_brightness('#ff0000', 50); // would make it 50% brighter
function increase_brightness(hex, percent){
// strip the leading # if it's there
hex = hex.replace(/^\s*#|\s*$/g, '');
// convert 3 char codes --> 6, e.g. `E0F` --> `EE00FF`
if(hex.length == 3){
hex = hex.replace(/(.)/g, '$1$1');
}
var r = parseInt(hex.substr(0, 2), 16),
g = parseInt(hex.substr(2, 2), 16),
b = parseInt(hex.substr(4, 2), 16);
return '#' +
((0|(1<<8) + r + (256 - r) * percent / 100).toString(16)).substr(1) +
((0|(1<<8) + g + (256 - g) * percent / 100).toString(16)).substr(1) +
((0|(1<<8) + b + (256 - b) * percent / 100).toString(16)).substr(1);
}
/**
* ('#000000', 50) --> #808080
* ('#EEEEEE', 25) --> #F2F2F2
* ('EEE , 25) --> #F2F2F2
**/
Update
#zyklus's answer is simpler and has the same effect. Please refer to this answer only if you are interested in converting between RGB and HSL.
To set the brightness of RGB:
Convert RGB to HSL
Set the brightness of HSL
Convert back from HSL to RGB
This link used to have code to convert RGB to HSL and reverse:
http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*/
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* #param Number h The hue
* #param Number s The saturation
* #param Number l The lightness
* #return Array The RGB representation
*/
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [r * 255, g * 255, b * 255];
}
I made some example with it. Check this link: http://jsfiddle.net/sangdol/euSLy/4/
And this is the increase_brightness() function:
function increase_brightness(rgbcode, percent) {
var r = parseInt(rgbcode.slice(1, 3), 16),
g = parseInt(rgbcode.slice(3, 5), 16),
b = parseInt(rgbcode.slice(5, 7), 16),
HSL = rgbToHsl(r, g, b),
newBrightness = HSL[2] + HSL[2] * (percent / 100),
RGB;
RGB = hslToRgb(HSL[0], HSL[1], newBrightness);
rgbcode = '#'
+ convertToTwoDigitHexCodeFromDecimal(RGB[0])
+ convertToTwoDigitHexCodeFromDecimal(RGB[1])
+ convertToTwoDigitHexCodeFromDecimal(RGB[2]);
return rgbcode;
}
function convertToTwoDigitHexCodeFromDecimal(decimal){
var code = Math.round(decimal).toString(16);
(code.length > 1) || (code = '0' + code);
return code;
}
You can pass a negative value as a percent argument to make it darken.
In case anyone needs it, I converted the color brightness JavaScript code to ASP / VBScript for a project and thought I would share it with you:
'::Color Brightness (0-100)
'ex. ColorBrightness("#FF0000",25) 'Darker
'ex. ColorBrightness("#FF0000",50) 'Mid
'ex. ColorBrightness("#FF0000",75) 'Lighter
Function ColorBrightness(strRGB,intBrite)
strRGB = Replace(strRGB,"#","")
r = CInt("&h" & Mid(strRGB,1,2))
g = CInt("&h" & Mid(strRGB,3,2))
b = CInt("&h" & Mid(strRGB,5,2))
arrHSL = RGBtoHSL(r, g, b)
dblOrigBrite = CDbl(arrHSL(2) * 100)
arrRGB = HSLtoRGB(arrHSL(0), arrHSL(1), intBrite/100)
newRGB = "#" & HEXtoDEC(arrRGB(0)) & HEXtoDEC(arrRGB(1)) & HEXtoDEC(arrRGB(2))
ColorBrightness = newRGB
End Function
'::RGB to HSL Function
Function RGBtoHSL(r,g,b)
r = CDbl(r/255)
g = CDbl(g/255)
b = CDbl(b/255)
max = CDbl(MaxCalc(r & "," & g & "," & b))
min = CDbl(MinCalc(r & "," & g & "," & b))
h = CDbl((max + min) / 2)
s = CDbl((max + min) / 2)
l = CDbl((max + min) / 2)
If max = min Then
h = 0
s = 0
Else
d = max - min
s = IIf(l > 0.5, d / (2 - max - min), d / (max + min))
Select Case CStr(max)
Case CStr(r)
h = (g - b) / d + (IIf(g < b, 6, 0))
Case CStr(g)
h = (b - r) / d + 2
Case CStr(b)
h = (r - g) / d + 4
End Select
h = h / 6
End If
RGBtoHSL = Split(h & "," & s & "," & l, ",")
End Function
'::HSL to RGB Function
Function HSLtoRGB(h,s,l)
If s = 0 Then
r = l
g = l
b = l
Else
q = IIf(l < 0.5, l * (1 + s), l + s - l * s)
p = 2 * l - q
r = HUEtoRGB(p, q, h + 1/3)
g = HUEtoRGB(p, q, h)
b = HUEtoRGB(p, q, h - 1/3)
End If
HSLtoRGB = Split(r * 255 & "," & g * 255 & "," & b * 255, ",")
End Function
'::Hue to RGB Function
Function HUEtoRGB(p,q,t)
If CDbl(t) < 0 Then t = t + 1
If CDbl(t) > 1 Then t = t - 1
If CDbl(t) < (1/6) Then
HUEtoRGB = p + (q - p) * 6 * t
Exit Function
End If
If CDbl(t) < (1/2) Then
HUEtoRGB = q
Exit Function
End If
If CDbl(t) < (2/3) Then
HUEtoRGB = p + (q - p) * (2/3 - t) * 6
Exit Function
End If
HUEtoRGB = p
End Function
'::Hex to Decimal Function
Function HEXtoDEC(d)
h = Hex(Round(d,0))
h = Right(String(2,"0") & h,2)
HEXtoDEC = h
End Function
'::Max Function
Function MaxCalc(valList)
valList = Split(valList,",")
b = 0
For v = 0 To UBound(valList)
a = valList(v)
If CDbl(a) > CDbl(b) Then b = a
Next
MaxCalc = b
End Function
'::Min Function
Function MinCalc(valList)
valList = Split(valList,",")
For v = 0 To UBound(valList)
a = valList(v)
If b = "" Then b = a
If CDbl(a) < CDbl(b) AND b <> "" Then b = a
Next
MinCalc = b
End Function
'::IIf Emulation Function
Function IIf(condition,conTrue,conFalse)
If (condition) Then
IIf = conTrue
Else
IIf = conFalse
End If
End Function
That way you won't need any conversion of the source color.
check out this fiddle : https://jsfiddle.net/4c47otou/
increase_brightness = function(color,percent){
var ctx = document.createElement('canvas').getContext('2d');
ctx.fillStyle = color;
ctx.fillRect(0,0,1,1);
var color = ctx.getImageData(0,0,1,1);
var r = color.data[0] + Math.floor( percent / 100 * 255 );
var g = color.data[1] + Math.floor( percent / 100 * 255 );
var b = color.data[2] + Math.floor( percent / 100 * 255 );
return 'rgb('+r+','+g+','+b+')';
}
Example usage :
increase_brightness('#0000ff',20);
increase_brightness('khaki',20);
increase_brightness('rgb(12, 7, 54)',20);
// color is a hex color like #aaaaaa and percent is a float, 1.00=100%
// increasing a color by 50% means a percent value of 1.5
function brighten(color, percent) {
var r=parseInt(color.substr(1,2),16);
var g=parseInt(color.substr(3,2),16);
var b=parseInt(color.substr(5,2),16);
return '#'+
Math.min(255,Math.floor(r*percent)).toString(16)+
Math.min(255,Math.floor(g*percent)).toString(16)+
Math.min(255,Math.floor(b*percent)).toString(16);
}
Live sample: http://jsfiddle.net/emM55/
Here is the increaseBrightness function with the RGB->HSL->RGB method. "amount" should be in percent.
HSL<->RGB conversion functions taken from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
function increaseBrightness( color, amount ) {
var r = parseInt(color.substr(1, 2), 16);
var g = parseInt(color.substr(3, 2), 16);
var b = parseInt(color.substr(5, 2), 16);
hsl = rgbToHsl( r, g, b );
hsl.l += hsl.l + (amount / 100);
if( hsl.l > 1 ) hsl.l = 1;
rgb = hslToRgb( hsl.h, hsl.s, hsl.l );
var v = rgb.b | (rgb.g << 8) | (rgb.r << 16);
return '#' + v.toString(16);
}
function rgbToHsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return {'h':h, 's':s, 'l':l};
}
function hslToRgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return { 'r':r * 255, 'g':g * 255, 'b':b * 255 };
}
I found a variation of Sanghyun Lee's reply generates the best result.
Convert RGB to HSL
Set the brightness of HSL
Convert back from HSLto RGB
The difference/variation is how you increase/decrease the brightness.
newBrightness = HSL[2] + HSL[2] * (percent / 100) // Original code
Instead of applying a percentage on the current brightness, it works better if it is treated as absolute increment/decrement. Since the luminosity range is 0 to 1, the percent can be applied on the whole range (1 - 0) * percent/100.
newBrightness = HSL[2] + (percent / 100);
newBrightness = Math.max(0, Math.min(1, newBrightness));
Another nice property of this approach is increment & decrement negate each other.
Image below shows darker and lighter colors with 5% increment. Note, how the palette is reasonably smooth and often ends with black and white.
Palette with original approach - gets stuck at certain colors.
I know this an old question, but I found no answer that simply manipulates css hsl color. I found the old answers here to be too complex and slow, even producing poor results, so a different approach seems warranted. The following alternative is much more performant and less complex.
Of course, this answer requires you to use hsl colors throughout your app, otherwise you still have to do a bunch of conversions! Though, if you need to manipulate brightness eg in a game loop, you should be using hsl values anyway as they are much better suited for programmatic manipulation. The only drawback with hsl from rgb as far as I can tell, is that it's harder to "read" what hue you're seeing like you can with rgb strings.
function toHslArray(hslCss) {
let sep = hslCss.indexOf(",") > -1 ? "," : " "
return hslCss.substr(4).split(")")[0].split(sep)
}
function adjustHslBrightness(color, percent) {
let hsl = toHslArray(color)
return "hsl(" + hsl[0] + "," + hsl[1] + ", " + (percent + "%") + ")"
}
let hsl = "hsl(200, 40%, 40%)"
let hsl2 = adjustHslBrightness(hsl, 80)
function brighten(color, c) {
const calc = (sub1,sub2)=> Math.min(255,Math.floor(parseInt(color.substr(sub1,sub2),16)*c)).toString(16).padStart(2,"0")
return `#${calc(1,2)}${calc(3,2)}${calc(5,2)}`
}
const res = brighten("#23DA4C", .5) // "#116d26"
console.log(res)
What I use:
//hex can be string or number
//rate: 1 keeps the color same. < 1 darken. > 1 lighten.
//to_string: set to true if you want the return value in string
function change_brightness(hex, rate, to_string = false) {
if (typeof hex === 'string') {
hex = hex.replace(/^\s*#|\s*$/g, '');
} else {
hex = hex.toString(16);
}
if (hex.length == 3) {
hex = hex.replace(/(.)/g, '$1$1');
} else {
hex = ("000000" + hex).slice(-6);
}
let r = parseInt(hex.substr(0, 2), 16);
let g = parseInt(hex.substr(2, 2), 16);
let b = parseInt(hex.substr(4, 2), 16);
let h, s, v;
[h, s, v] = rgb2hsv(r, g, b);
v = parseInt(v * rate);
[r, g, b] = hsv2rgb(h, s, v);
hex = ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
if (to_string) return "#" + hex;
return parseInt(hex, 16);
}
function rgb2hsv(r,g,b) {
let v = Math.max(r,g,b), n = v-Math.min(r,g,b);
let h = n && ((v === r) ? (g-b)/n : ((v === g) ? 2+(b-r)/n : 4+(r-g)/n));
return [60*(h<0?h+6:h), v&&n/v, v];
}
function hsv2rgb(h,s,v) {
let f = (n,k=(n+h/60)%6) => v - v*s*Math.max( Math.min(k,4-k,1), 0);
return [f(5),f(3),f(1)];
}
A variant with lodash:
// color('#EBEDF0', 30)
color(hex, percent) {
return '#' + _(hex.replace('#', '')).chunk(2)
.map(v => parseInt(v.join(''), 16))
.map(v => ((0 | (1 << 8) + v + (256 - v) * percent / 100).toString(16))
.substr(1)).join('');
}
First get a quick understanding of hex color codes.
Then it should be pretty easy to break down your color value into RGB, make the adjustments and then return the new color code.

Categories