good chemistry is complicated,and a little bit messy -LW PerlMonks

### Re: Re: Shading with HTML colors - color_munge

by Vondikall (Initiate)
 on Mar 29, 2001 at 14:10 UTC ( #68072=note: print w/replies, xml ) Need Help??

Here's code to convert from rgb to Lab and back again. I am using this to convert an RGB rep of an HTML color to it's Lab equivalent, raising or lowering the Luminance part and then converting back again to an RGB value and thence to an HTML color.

I couldn't find anything about cube roots, hence the _cuberoot and _cube

```# I do not do the linear approximation for \$u/\$un <= 0.008859
sub RGB2Lab {
my (\$red, \$green, \$blue) = @_;

my (\$x, \$y, \$z)    = _RGB2XYZitu(\$red, \$green, \$blue);
my (\$xn, \$yn, \$zn) = _RGB2XYZitu(1,1,1);
my \$fx = _cuberoot(\$x/\$xn);
my \$fy = _cuberoot(\$y/\$yn);
my \$fz = _cuberoot(\$z/\$zn);

return ( 116*\$fy-16, 500*(\$fx - \$fy), 200*(\$fy - \$fz) );

}

sub Lab2RGB {
my (\$L, \$a, \$b) = @_;
my (\$xn, \$yn, \$zn) = _RGB2XYZitu(1,1,1);

my \$fL = _cube((\$L+16)/116);
my \$fa = _cube(\$a/500);
my \$fb = _cube(\$b/200);

my \$y = _cube( (\$L+16)/116) * \$yn;
my \$x = _cube( (\$L+16)/116 + \$a/500 ) * \$xn;
my \$z = _cube( (\$L+16)/116 - \$b/200 ) * \$zn;

return _XYZitu2RGB(\$x, \$y, \$z);

}

sub _RGB2XYZitu {
my (\$r, \$g, \$b) = @_;
return (
0.431*\$r + 0.342*\$g + 0.178*\$b,
0.222*\$r + 0.707*\$g + 0.071*\$b,
0.020*\$r + 0.130*\$g + 0.939*\$b
);
}

sub _XYZitu2RGB {
my (\$x, \$y, \$z) = @_;

return  map { \$_ > 1 ? 1 : \$_ } (
3.063*\$x - 1.393*\$y - 0.476*\$z,
-0.969*\$x + 1.876*\$y + 0.042*\$z,
0.068*\$x - 0.229*\$y + 1.069*\$z
);

}

sub _cuberoot {
my \$x = shift;
return 0 if \$x == 0;
my \$sign = (\$x < 0) ? -1 : 1;
\$x *= \$sign;
return \$sign * exp( log(\$x)/3.0 );
}

sub _cube {
my \$x = shift;
return 0 if \$x == 0;
my \$sign = (\$x < 0) ? -1 : 1;
\$x *= \$sign;
return \$sign * exp( 3 * log(\$x) );
}

Replies are listed 'Best First'.
Re: Re: Re: Shading with HTML colors - color_munge
by merlyn (Sage) on Mar 29, 2001 at 19:34 UTC
Your _cube can be replaced with:
```sub _cube { \$_[0] ** 3 }
but _cuberoot is a bit tougher if it might have negative bases:
```sub _cuberoot {
my \$res = abs(\$_[0])**(1/3);
\$_[0] < 0 ? -\$res : \$res;
}
Re^3: Shading with HTML colors - color_munge
by Anonymous Monk on Sep 18, 2012 at 08:20 UTC
Thanks!!!

Create A New User
Node Status?
node history
Node Type: note [id://68072]
help
Chatterbox?
 [LanX]: inspect %INC ? [Lady_Aleena]: LanX, for every module I've written? [huck]: Lady_Aleena see Re: pl script in webserver and/or Re: pl script in webserver for what they use [Lady_Aleena]: Wouldn't I have to run the modules somehow to get their %INC? [huck]: the first one works just fine from the command line but requires editing [huck]: but neither will handle autoloads

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2017-05-27 00:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My favorite model of computation is ...

Results (192 votes). Check out past polls.