PDA

View Full Version : how to get random colors with same hue?


V@no.
01-15-2004, 04:23 AM
Hi!
I'm trying figure out how to get a random color (HEX or DEC) but with same luminance value?
or, maybe lets say, I got an three random numbers from 0 to 255, (RGB), then how do I udjust them to get a specific luminance level?
is there any math formulas for that? Anyone knows?

Thank you.

firepages
01-15-2004, 07:46 AM
Hi I moved this to general as its not a PHP related question (not sure this is the right forum either but anyway ;) ), I have seen javascripts that do exactly what you are talking about , perhaps google for such ? or hopefully someone here will have a pointer.

V@no.
01-15-2004, 12:03 PM
ah, wait, that's the reason I posted in PHP forum, because I need it for PHP...I thought maybe someone has compleate code in php, or atleast a math formula, witch hopefuly I could translate in php...
I know formula on how to get gradient colors between two colors, but I dont know how to calculate luminance...


P.S. In my original post I made a mistake, I asked about hue, witch actualy I ment luminance...

liorean
01-15-2004, 04:07 PM
Why don't you convert the colour from RGB to HSL? Then you can easily do what manipulations you want within the same hue, saturation or lightness by only manipulating the other two values. The algorithm for conversion between the formats is simple:
HOW TO RETURN hsl.to.rgb(h, s, l):
SELECT:
l<=0.5: PUT l*(s+1) IN m2
ELSE: PUT l+s-l*s IN m2
PUT l*2-m2 IN m1
PUT hue.to.rgb(m1, m2, h+1/3) IN r
PUT hue.to.rgb(m1, m2, h ) IN g
PUT hue.to.rgb(m1, m2, h-1/3) IN b
RETURN (r, g, b)

HOW TO RETURN hue.to.rgb(m1, m2, h):
IF h<0: PUT h+1 IN h
IF h>1: PUT h-1 IN h
IF h*6<1: RETURN m1+(m2-m1)*h*6
IF h*2<1: RETURN m2
IF h*3<2: RETURN m1+(m2-m1)*(2/3-h)*6
RETURN m1
This code was written in the ABC language, and taken directly out of the [CSS3 Color] (http://www.w3.org/TR/css3-color/#hsla-color) module. h, s and l are fractions in the interval 0..1. It should be fairly easily converted into php, or JavaScript, or any other language you might want to use.

V@no.
01-15-2004, 10:34 PM
Thanks, but the problem is that I have no idea what HSL is...and how to work with it...

kansel
01-15-2004, 10:46 PM
HSL is the color space you are trying to access. You specify _Hue in the title of your message, then refer to _Luminance twice in your post. These are the H and L of HSL. The S is _Saturation.

When you convert from RGB to HSL you can manipulate just the L value and come up with colors of the same hue and saturation but different luminance (lightness). Likewise you can manipulate just the H value giving completely different colors with the same saturation and luminance.

liorean
01-15-2004, 10:53 PM
HSL and RGB are both methods of representing a colour value. HSL, Hue-Saturation-Lightness is described in the link I gave you, to [CSS3 Color].

If you look in any average to advanced graphics creation and editing program, you will find ways of representing colours using HSL instead of RGB. HSL has the direct benefit that you can easier find colours that match pretty well, because you can modify just one of the values to achieve the result, where you have to modify all three to achieve the same in RGB format.

V@no.
01-15-2004, 10:53 PM
Originally posted by kansel
You specify _Hue in the title of your message, then refer to _Luminance twice in your post.yes, sorry, I actualy ment luminance, I've edited my original post but the title didnt change...

Thank you very much, not I understand what u ment, and it sounds pretty much easy. All I need to do now is convert ABC code into PHP.

P.S. never heard of ABC language before..:o

liorean
01-15-2004, 10:57 PM
I've heard of it, but never seen it used before. It's benefit is that it is very easy to read as text, and that it at the same time makes it easy to represent mathematical equations or algorithms.

kansel
01-15-2004, 11:02 PM
Let me clarify that last post a bit.

Say you have a color #FF0000. (bright red)

You can specify this color in RGB colorspace with hexadecimal as above, integer (255,0,0), decimal (1,0,0) or any other ranges you want.

There exists a relationship between the values of this color's Red, Green and Blue components that can be translated into Hue, Saturation and Luminance. The relationship is the algorithm that liorean posted above.

The algorithm converts the RGB values into values of HSL in the range 0..1. Thus FF0000 would look something like 0,1,.5 (I'll leave it to someone else to work out the exact numbers). Where 0 is the Hue (I think in one algorithm I saw, pure red comes out as undefined but assumed 0), 1 is the Saturation (all of the available color is used) and 0.5 is the Luminance (where 0 would be black and 1 would be white).

If you've used Photoshop or have seen a color palette/selector on the computer you might have tried changing the H, S or L values. When doing this, the computer automatically changes the R, G and B values (and vice-versa).

Just as modifying only the R component of an RGB value will increase or decrease the amount of red in a color, changing the H component of an HSL value will alter the color hue along a scale that looks roughly like Red Yellow Green Blue Magenta. Changing only the S component will increase or decrease the intensity of a color (0 is gray, 1 is as pure as possible) and changing only the L component will make the color lighter or darker.

So what the heck do you do with this?

When you convert the color from RGB into HSL, play with the numbers, then convert back from HSL into RGB and you can use the new color however you want.

Actually now that I look more closely at the above posts, it looks like the algorithm to convert RGB into HSL is missing. I have one I got from a 25 year old book that I don't believe is very reliable, but I'm willing to post it here if you request it, or maybe liorean will be kind enough to track that down.

bah! I put too much time into my posts. sorry if this didn't add anything to the thread

liorean
01-16-2004, 01:09 AM
Ok, this is JavaScript and not PHP:function fnRgbToHsl(r, g, b){ // R G B as integers, 0..255.
r /= 255;
g /= 255;
b /= 255;
var
max = Math.max(r, g, b),
min = Math.min(r, g, b),
l = (max + min) / 2;
h = 0,
s = 0;
if(max != min){
s = (l < .5)?
(max - min) / (max + min):
(max - min) / (2 - max - min)
h = (max != r)?
(max != g)?
4 * (r - g) / (max - min):
2 * (b - r) / (max - min):
(g - b) / (max - min);
}
h *= 60;
if(h < 0)
h += 360;
return [h, s, l];
}

function fnHslToRgb(h, s, l){ // H as degrees 0..360, S L as decimals, 0..1.
h /= 360;
function fnHueToRgb(x, y, h){
if(h < 0)
h += 1;
else if(h > 1)
h -= 1;
return ((h * 6 < 1)?
x +(y - x) * h * 6:
(h * 2 < 1)?
y:
(h * 3 < 2)?
x + (y - x) * (2 / 3 - h) * 6:
x);
}
var
y = (l > .5)?
l + s - l * s:
l * (s + 1),
x = l * 2 - y,
r = fnHueToRgb(x, y, h + 1 / 3) * 255,
g = fnHueToRgb(x, y, h) * 255,
b = fnHueToRgb(x, y, h - 1 / 3) * 255;
return [r, g, b];
}

(Untested)

V@no.
01-16-2004, 01:48 AM
Thank you very much, guys. Your info is very informative and usefull!
I finaly found PHP functions (http://theril.mine.nu/code/phpblend.phps)

Now, I have another question:
as u know in most graphic tools, editors, the color picker has RGB and SHL fields. Both of them uses numbers from 0 to 255, but as u mentioned above, HSL uses numbers from 0 to 1
How do I go around that? I need numbers from 0 to 255

Thanks.

liorean
01-16-2004, 01:55 AM
In fact, HSL is usually presented as degrees for hue, percentage for the other two. To get a decimal converted into a degree, multiply by 360. To get a decimal converted into an 8-bit value, multiply with 255. To get a decimal converted into a percentage, multiply by 100. In all cases, you should round the result, possibly allowing a single decimal on the percentages.

Terry
01-31-2004, 03:51 AM
This is just the post I've been looking for. I've been making a major improvement script based upon the popular http://www.colorschemer.com/online.html

All the deatails aren't worked out yet but the just of it is based upon the fact that this site is not exactly a standards-based implementation. I am trying to do the same function as you guys are talking about. I've also been researching the algorithm that makes it work. Influences include:
http://www.hypermedic.com/colors/colortable.htm
http://www.cs.rit.edu/~ncs/color/t_convert.html
http://www.colorschemer.com/online.html
http://www.easyrgb.com/math.html
http://www.hypermedic.com/color/index.php
http://www.javascripter.net/faq/rgbtohex.htm

Anyway, here's the func:

function rgb_to_hsl(R,G,B)
{

var Min, Max, H, S, L;

R = ((R/51) * .2), G = ((G/51) * .2), B = ((B/51) * .2);

Min = Math.min( R, Math.min(G, B) ); // Min. value of RGB
Max = Math.max( R, Math.max(G, B) ); // Max. value of RGB
L = (Max + Min) / 2;
if(Max == Min) { S = H = 0; }
else
{
if(L < 0.5)
S = (Max-Min) / (Max+Min);
if(L >= 0.5)
S = (Max-Min) / (2-Max-Min);
switch(Max)
{
case R: H = (G-B) / (Max-Min); break;
case G: H = 2 + ( (B-R) / (Max-Min) ); break;
case B: H = 4 + ( (R-G) / (Max-Min) ); break;
}
}
H = Math.round(H*60);
if(H < 0) H += 360;
if(H >= 360) H -= 360;
S = Math.round(S*100);
L = Math.round(L*100);

alert(H +" , "+ S +" , "+ L);
}


Any suggestions or improvements, especially as relating to a more compact implementation, is welcomed. Also, if someone has a comparable hsl_to_rgb, that would be much appreciated :) I understand the algorithm, to a point, but I'm not completely sure if I can reverse it successfully. Skill in algorithms directly equal a proficiency in math ... and that is not my strong point!

Terry