Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Shading with HTML colors - color_munge

by $code or die (Deacon)
on Feb 27, 2001 at 21:52 UTC ( #61111=snippet: print w/replies, xml ) Need Help??
Description: Background: I wanted a way of displaying some html with different shading depending on a given criterion. I didn't want completely different colors - 1 color with different levels of brightness.

This snippet will convert a hex color to RGB, shift the levels up and down by a given value, then convert back to HTML valid HEX (not necessarily web-safe). It returns:
1. lighter color than orig. 2. darker color than orig.

Potential Uses: Well, I am using this for a diary system, the cells in the month-view-calendar will be shaded diferently depending on how many meetings\reminders I have on that day. But I am sure you can thing of other reasons to do it.

Notes: It might not work so well when any of the RGB values are close to 0 or 255. There may also be a neater way of doing it.... Comments welcome...
my $silver = "c0c0c0";
my ($light_silver, $dark_silver) = color_munge(25,$silver);

sub color_munge {
    my @limits = (0, 255);
    my $off_set = shift;
    my $html_colour = shift;

    my @old = map hex, ($html_colour =~ /(..)(..)(..)/);
    my $brighter = join ('', map {$_ += $off_set; $_ = $limits[1] if $
+_ > $limits[1]; sprintf("%02X", $_); } @old);

    my $darker = join('', map {$_ -= 2 * $off_set; $_ = $limits[0] if 
+$_ < $limits[0]; sprintf("%02X", $_); } @old);
    return ($brighter,$darker);

Replies are listed 'Best First'.
Re: Shading with HTML colors - color_munge
by merlyn (Sage) on Feb 27, 2001 at 22:06 UTC
    A mapping to and from HSV space might be appropriate. I'm not sure if there's already modules in the CPAN for that, but someone here might have the formulas.

    -- Randal L. Schwartz, Perl hacker

      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) ); }
Re: Shading with HTML colors - color_munge
by $code or die (Deacon) on Feb 27, 2001 at 22:48 UTC
    A couple of links about HSV - I'll post a new version of the above snippet once I get my head round HSV, HLS, etc... AI color matching!
    Color Spaces

    -no space for a sig-
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://61111]
[choroba]: it depends. Give more details, please
[thepkd]: i used a series of {}'s but it dont work
[choroba]: You need square brackets for arrays
[GotToBTru]: you can certainly construct a single expression to access any part of the data structure, without using temp variables. but you might make it easier on yourself and any other poor soul who has to understand your code if you do
[thepkd]: to dereference i mean
LanX .oO( oh tempz, oh moretz)
[thepkd]: @GotToBTru Sure. But.
choroba waits

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (13)
As of 2016-12-06 13:27 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (104 votes). Check out past polls.