Allegro.cc - Online Community

Allegro.cc Forums » Off-Topic Ordeals » openlayer HLS colourspace

This thread is locked; no one can reply to it. rss feed Print
openlayer HLS colourspace
fuzinavl
Member #4,105
December 2003
avatar

openlayer feature request:

Hlsa( float hue, float lightness, float saturation, float alpha = 1.0)
{
   //returns an Rgba object or 32-bit packed pixel ???
   //therefore can be used anywhere Rgba(,,,) is used. :)
}

__________________________
fuzinavl@hotmail.com (Pittsburgh)
__http://fuzinavl.tripod.com/__

Krzysztof Kluczek
Member #4,191
January 2004
avatar

hsv_to_rgb
Click. You can use this function to convert HSV->RGB and then makecol or proper OpenLayer function to convert it to OpenLeyar color. It should work (unless you need exactly HSL and HSV isn't enough). :)

Fladimir da Gorf
Member #1,565
October 2001
avatar

Well, just give me the equations and I'll implement it ;)

That might be useful, but it requires a named constructor as the parameter types are the same as with the RGBA constructor.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Thomas Harte
Member #33
April 2000
avatar

Quote:

Well, just give me the equations and I'll implement it

Here you go:

http://www.easyrgb.com/math.php

I haven't read that page at all, but from memory all the ordinary colour conversions are just linear transforms so you could abstract it with a 3x3 matrix for every colour space conversion. Unless you want also to provide support for both linear and exponential scales, but that doesn't seem to be part of the request!

EDIT: completely off topic, but while you're here and because I've just been messing around on an OpenGL thingy myself - does OpenLayer prefer GL_ARB_texture_non_power_of_two to GL_ARB/EXT/NV_texture_rectangle where both are available?

Krzysztof Kluczek
Member #4,191
January 2004
avatar

Quote:

I haven't read that page at all, but from memory all the ordinary colour conversions are just linear transforms so you could abstract it with a 3x3 matrix for every colour space conversion.

This is not the case for HSV and HSL, as H is in fact an angle (0 is red, 0.33 is green, 0.67 is blue and 1 is red again).

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

does OpenLayer prefer GL_ARB_texture_non_power_of_two to GL_ARB/EXT/NV_texture_rectangle where both are available?

Well, OpenLayer doesn't support the *_texture_rectangle extensions yet. But since the GL_ARB_texture_non_power_of_two extension doesn't require using an another texture target it sounds better... especially as no code has to be changed in order to support it. Performance wise I don't know.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

Andrei Ellman
Member #3,434
April 2003

Here is an implementation of RGB <-> HLS colourspace conversion code. This particular implementation uses the same scale of units as Allegro's RGB <-> HSV functions. This is to maintain consistency with Allegro's functions, but this could be speeded up by making it accept a hue in the range 0..6 instead of 0..360

hls_to_rgb:

1 
2#include <math.h>
3#include <float.h>
4 
5 
6/* hls_to_rgb:
7 * Converts from HLS colorspace to RGB values.
8 * Taken From Foley & VanDam Fig. 13.37 with a few modifications.
9 */
10 
11 
12/* The function proper */
13void hls_to_rgb (float h, float l, float s, int *r, int *g, int *b)
14{
15 float m1, m2;
16 
17 l*=255.0f;
18 
19 if (s < FLT_EPSILON) { /* greyscale */
20 *r = *g = *b = (int)(l+0.5f);
21 } else {
22 /* Work out min and max of the r,g,b sliders */
23 m2 = (l<=127.5f) ? (l+(l*s)) : (l+(s*255.0f) - (l*s)); /* Max RGB value */
24 m1 = l+l - m2; /* Min RGB value */
25 /* l is average of m1 and m2. */
26 
27 // ex m2 = (l<=0.5f) ? (l+(l*s)) : (l+s - (l*s));
28 // ex m1 = 2.0f * l - m2;
29 
30 
31 // m2 = l + (l*s);
32 // m1 = l - (l*s);
33 // m2-m1 = l + (l*s) - l + (l*s) = 2*(l*s)
34 
35 
36 // m2 = l+s - (l*s);
37 // m1 = l-s + (l*s);
38 // m2-m1 = l+s - (l*s) - l+s - (l*s) = 2*s - 2*(l*s) = 2*(s-l*s)
39 
40 
41 
42 h = fmod(h, 360.0f) / 60.0f;
43 if (h < 0.0f) {
44 h += 6.0f;
45 }
46 
47 
48 m1+=0.5f;
49 m2+=0.5f;
50 
51 
52 if(h < 3.0f) {
53 if(h < 2.0f) {
54 if(h < 1.0f) {
55 /* 0<=h<1 */
56 *r = (int)m2;
57 *g = (int)(m1+(m2-m1)*h);
58 *b = (int)m1;
59 }
60 else {
61 /* 1<=h<2 */
62 *r = (int)(m1+(m2-m1)*(2.0f-h));
63 *g = (int)m2;
64 *b = (int)m1;
65 }
66 }
67 else {
68 /* 2<=h<3 */
69 *r = (int)m1;
70 *g = (int)m2;
71 *b = (int)(m1+(m2-m1)*(h-2.0f));
72 }
73 }
74 else {
75 if(h < 5.0f) {
76 if(h < 4.0f) {
77 /* 3<=h<4 */
78 *r = (int)m1;
79 *g = (int)(m1+(m2-m1)*(4.0f-h));
80 *b = (int)m2;
81 }
82 else {
83 /* 4<=h<5 */
84 *r = (int)(m1+(m2-m1)*(h-4.0f));
85 *g = (int)m1;
86 *b = (int)m2;
87 }
88 }
89 else {
90 /* 5<=h<6 */
91 *r = (int)m2;
92 *g = (int)m1;
93 *b = (int)(m1+(m2-m1)*(6.0f-h));
94 }
95 }
96 }
97 
98 
99} /* End of hls_to_rgb */

rgb_to_hls:

1 
2#include <math.h>
3#include <float.h>
4 
5/* rgb_to_hls:
6 * Converts an RGB value into the HLS colorspace.
7 * Taken From Foley & VanDam Fig. 13.36 with a few modifications.
8 */
9void rgb_to_hls(int r, int g, int b, float *h, float *l, float *s)
10{
11 float min, max, delta, rc, gc, bc;
12 
13 rc = (float)r / 255.0f;
14 gc = (float)g / 255.0f;
15 bc = (float)b / 255.0f;
16 
17 max = MAX(rc, MAX(gc, bc));
18 min = MIN(rc, MIN(gc, bc));
19 
20 *l = (max+min)/2.0f; /* L is the average of maximum and minimum r,g,b */
21 
22 delta = max - min;
23 
24 // note: if using ints, will not need this epsilon thing.
25 // we could do the divide by 255 AFTER we work out Delta.
26 
27 if (delta<FLT_EPSILON) {
28 /* Somewhere along the centre axis of the double-hex-cone (s==0) */
29 *s = 0.0f; /* color has no saturation */
30 *h = 0.0f; /* color has no hue */
31 
32 } else {
33 
34 /* Calculate Saturation */
35 *s = (*l<=0.5f) ? (delta/(max+min)) : (delta/(2.0f-(max+min)));
36 
37 
38 /* Calculate Hue */
39 if (rc == max)
40 *h = (gc-bc) / delta; /* Resulting color between yellow & magenta */
41 else if (gc == max)
42 *h = 2.0f + (bc-rc) / delta; /* Resulting color between cyan & yellow */
43 else /* if (bc == max) */
44 *h = 4.0f + (rc-gc) / delta; /* Resulting color between magenta & cyan */
45 
46 if (*h < 0.0f)
47 *h += 6.0f; /* Make sure hue is non-negative */
48 
49 *h *= 60.0f;
50 }
51 
52} /* End of rgb_to_hls */

If you want to convert a float value from 0..1 to an int value from 0..0xff, then use the following macro

#define ap01FTO0255INT(fl) ((int)(fl * 255.0f + 0.5f))

For converting a foat value from 0..360 to an int value from 0..0x600, use this:

#define ap0360FTO01536INT(fl) ((int)(fl * 1536.0f / 360.0f + 0.5f))  /* 0x600 = 1536 */

Note that because Hue is a cyclic paramater, the range of conversion is 0..0x600 rather than 0..0x5FF . However, due to the nature of the input values (the nature being that they are only 8-bit RGB values), no likely set of inputs to rgb_to_hls() (or for that matter, rgb_to_hsv()) is going to yield a value greater than 0x5FF. The hue wheel is divided into six segments, and each segment can produce 256 discrete values with 8-bit RGB colour. This means that ((256*6)-1) / (256*6) * 360 = 359.765625 (which is the maximum value of H that the function can yield for 8-bit RGB values), and plugging in 359.765625 to the macro above gives 1535.5, which when converted to a hexadecimal int, is rounded down to 0x5FF

I have implemented much faster versions of RGB <-> HLS and RGB <-> HSV, that takes the saturation and value as chars, and the hue as a short (no floats for the paramaters, but it still uses floats internally). This code can be found in the sourcecode of my ChromaPlas screensaver which also demonstrates a nice effect and shows the difference between HSV and HLS.

For further reading, see:
http://en.wikipedia.org/wiki/HSV_color_space
http://en.wikipedia.org/wiki/HSL_color_space

AE.

--
Don't let the illegitimates turn you into carbon.

fuzinavl
Member #4,105
December 2003
avatar

Woah there!
I'm not looking for a whole new object to maintain, Just a nice little one-way conversion utility-function.

int Hsva( float hue, float saturation, float value, float alpha = 1.0)
{
   int r,g,b = 0;
   hsv_to_rgb(hue, saturation, value, &r, &g, &b);

   return Rgba( r, g, b, int(alpha) * 255.0);  //I'm rusty with c++! Does this return an int?
}

int Hlsa( float hue, float lightness, float saturation, float alpha = 1.0)
{
   return Hsva( hue, saturation, lightness * 0.5f, alpha); //wrong wrong wrong wrong wrong!
}

__________________________
fuzinavl@hotmail.com (Pittsburgh)
__http://fuzinavl.tripod.com/__

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

//I'm rusty with c++! Does this return an int?

It's a constructor call which creates a new Rgba object. So the return value should be Rgba.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

fuzinavl
Member #4,105
December 2003
avatar

yay :D

1Rgba Hsva( float hue, float saturation, float value, float alpha = 1.0f)
2{ // h 0..6 s 0..1 v 0..1
3 int r,g,b = 0;
4 hsv_to_rgb(hue*60.0f, saturation, value, &r, &g, &b);
5 
6 return Rgba( r, g, b, int(alpha) * 255);
7}
8 
9//Rgba Hsla( float hue, float saturation, float lightness, float alpha = 1.0f){}
10//not implemented
11 
12Setup::SetupScreen( 800,600, WINDOWED );
13 
14while( !key[KEY_ESC] )
15{
16 Canvas::Fill( Hsva(float(mouse_x) * 6.0f / 800.0f, float(mouse_y)/600.0f , 1.0f) );
17 ol::Ellipse(mouse_x,mouse_y,10,10).Draw(Rgba::WHITE);
18 Canvas::Refresh();
19 rest(1);
20}

;D works!

__________________________
fuzinavl@hotmail.com (Pittsburgh)
__http://fuzinavl.tripod.com/__

Fladimir da Gorf
Member #1,565
October 2001
avatar

Quote:

int(alpha) * 255

I guess you mean:

int(alpha * 255)

Or otherwise the alpha would be rounded either to one or zero.

OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori)

fuzinavl
Member #4,105
December 2003
avatar

Thanks all!
Attached is the hue utility 1.0. :)

__________________________
fuzinavl@hotmail.com (Pittsburgh)
__http://fuzinavl.tripod.com/__

Go to: