# hsl to rgb

This topic is 3929 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

most hsl to rgb algorithms, much like the one here http://www.acm.org/tog/GraphicsGems/gems/HSLtoRGB.c show how to take the hsl values and transform them into rgb equivelents, but i've seen no explanation of how to apply a shift in hue, saturation or lightness to a pixel, using that output rgb value. does this call for a multiply/add filter against the pixel or something entirely different?

##### Share on other sites
Surely a shift in hue, saturation or lightness is simply an additive difference in whichever area. Just then convert this difference from HSL to RGB and then add it to the pixel values in RGB.

e.g.:

Increase of 25 in lightness -- H0 S0 L25
Convert to RGB
Add this converted RGB value to the existing RGB value

Now, I don't know if this would actually work, but it seems to make sense at the first look.

##### Share on other sites
hi, thanks for the reply, but that doesn't work. i tried alpha blending as well, but you're just merging a solid color with a pixel, so it comes out looking like a tint.

anyone else have any ideas/google/wiki searches that i havn't found?

##### Share on other sites
Any reason you can't just transform input rgb to hsl, make the change and transform back?

##### Share on other sites
Zahlman, no reason in particular. in fact, that's makes much more sense. i just haven't figured out how to compute the difference between the hsl representation of the current rgb, and the newly adjusted hsl.

for example, you have hsl_1, and hsl_2 (both 0.0 to 1.0, hsl_1 will obviously be different per pixel, and hsl_2 being the measure which all pixels will be re-calculated against).

i'm right there, but for some reason the answer just isn't obvious to me... :(

##### Share on other sites
Quote:
 Original post by flukeZahlman, no reason in particular. in fact, that's makes much more sense. i just haven't figured out how to compute the difference between the hsl representation of the current rgb, and the newly adjusted hsl.for example, you have hsl_1, and hsl_2 (both 0.0 to 1.0, hsl_1 will obviously be different per pixel, and hsl_2 being the measure which all pixels will be re-calculated against).i'm right there, but for some reason the answer just isn't obvious to me... :(

I'm sorry, but I can't really make any sense of that. What exactly are you trying to do? Try forgetting that RGB ever existed: given an HSL value (h1, s1, l2) input, what output do you want?

##### Share on other sites
HSL is a different model. A component-wise difference in RGB will produce two unrelated HSL values (unrelated in a sense that they will not be component-wise related to RGB changes).

Blending two colors in RGB is component-wise average (for example) ((R1+R2)/2, (G1+G2)/2,(B1+B2)/2).

But what happens in HSL is completely unrelated. Blending is not (H1+H2)/2, (S1+S2)/2,(L1+L2)/2). Or it might even be, but that would be a special case, didn't check.

For example, adjusting alpha in RGB means multiplying each component with a constant factor. In HSL, you merely adjust the L component, other two remain the same.

You cannot thing of HSL in the same way as RGB, they are completely different. So what you need is a transformation for your given problem in HSL or RGB. But you can't apply same transformation to both.

Or, simply put: RGB color is a vector within a normalized 3D cube with R,G and B components being the axis.

HSL model is different, it's a double cone, and is as such a non-linear transform of RGB model. Relations that hold between RGB colors do not hold between HSL colors.

Quote:
 Increase of 25 in lightness -- H0 S0 L25Convert to RGBAdd this converted RGB value to the existing RGB valueNow, I don't know if this would actually work, but it seems to make sense at the first look.

Unless I've missed something, this doesn't work.

You need to convert from RGB back to HSL, apply the transform, then convert back to RGB.

##### Share on other sites
Quote:
Original post by Antheus
Quote:
 Increase of 25 in lightness -- H0 S0 L25Convert to RGBAdd this converted RGB value to the existing RGB valueNow, I don't know if this would actually work, but it seems to make sense at the first look.

Unless I've missed something, this doesn't work.

You need to convert from RGB back to HSL, apply the transform, then convert back to RGB.

Thanks. As I say, whilst I know what HSL is and have done some work in graphics using it, I haven't ever converted from it to RGB or vice versa; I don't really have any intuitive handle on how the thing works.

##### Share on other sites
sorry, i should have posted this last night to save you guys some typing but i came pretty close to getting it working... i'm doing this from memory, so i've left out the type-casting and a few other things, but here's the general idea:

//the h1,s1,l1 group represents the h, s, and l of the current pixel//the h2,s2,l2 group represents what values are input from a slider in a dialogfor(y=0;y<h;y++){  for(x=0;x<w;x++){     //get RGB value of pixel here (r1,g1,b1)     //...     //...     RGB2HSL((r1/255),(g1/255),(b1/255),&h1,&s1,&l1); //1st get some working hsl vals     //now just shift the hsl val, based on the value/location of corresponding slider     if(h2<.5){          h1=h1-(.5-h2);     }else if(h2>.5){          h1=h1+(h2-.5);     }     //same conditional for saturation and lightness     HSL2RGB(h1,s1,l1,&r2,&g2,&b2); //  }}

it will shift the hue, but starts to have some issues as it nears 0 or 1 (can't remember which)

it will saturate/desaturation, but not fully... almost as though 0 and 1 are too restrictive

and it will lighten and darken what seems like just portions of the image where there are significant amounts of color. just my first impression. needs more evaluation.

finally, sorry about the confusion earlier. what makes sense in my head doesn't always convey well via text. i actually had a slightly better understanding of the differences between rgb and hsl than my badly formed questions/statements might have suggested. :)

##### Share on other sites
The 'hue' value should be treated cyclically; i.e. if you increase it just past 1 it should loop to 0 again, and if you decrease it just below 0 it should loop to 1 again. But otherwise it should work fine, as long as you have the conversion math correct (check for typos).

For saturation and lightness, these values effectively 'saturate' (pun intended) at 0 and 1, so that's not a problem... but consider that if your slider only allows an adjustment of +.5, and the initial value is less than .5, then you won't be able to reach full saturation/lightness with the slider.

Also, that's a horrible interface for your conversion functions. Create structures to represent RGB and HSL values (each just contains 3 floats), and have each function accept an instance of one (by const reference, assuming C++) and return an instance of the other (by value, of course).

Also, you don't need that branching logic. I see this kind of thing all the time and don't understand why so many people seem to *think* this way, when the simple way is perfectly obvious to me and always has been.

Hint: -(.5-h2) and +(h2-.5) are *equal*. :)

##### Share on other sites
I cannot recommend converting from RGB to HSL and then back to RGB again.

There is no guarantee that a color in one space is representable in the other.

Stick with full time HSL, and only convert to RGB for display approximation purposes.