Hey guys. Take a look at this:
function GenHEXOpacity($basecolor, $opacity) {
sscanf($basecolor, "%2x%2x%2x", $r, $g, $b); // convert HEX to RGB
$r = $r/255;
$g = $g/255;
$b = $b/255;
$MAX = max($r,$g,$b);
$MIN = min($r,$g,$b);
if ($MAX == $MIN) return array(0,0,$MAX);
if ($r == $MAX) $HUE = ((0 + (($g - $b)/($MAX-$MIN))) * 60);
elseif ($g == $MAX) $HUE = ((2 + (($b - $r)/($MAX-$MIN))) * 60);
elseif ($b == $MAX) $HUE = ((4 + (($r - $g)/($MAX-$MIN))) * 60);
if ( $HUE < 0 ) $HUE += 360;
$HSB = array($HUE,(($MAX - $MIN)/$MAX),$MAX); // HSB values extracted from RGB
$H = $HSB[0];
$S = $HSB[1]-($HSB[1]*($opacity/100)); // This is the challenge. Saturation modification is supposed to be non-linear (according to Photoshop). Right now I made it linear just to test stuff out. It's not 100% exact though...
$V = ((1-$HSB[2])*($opacity/100))+$HSB[2]; // Brightness is linear so it's a piece of cake!
if ($S == 0) return array($V * 255,$V * 255,$V * 255);
$Hi = floor($H/60);
$f = (($H/60) - $Hi);
$p = ($V * (1 - $S));
$q = ($V * (1 - ($S * $f)));
$t = ($V * (1 - ($S * (1 - $f))));
switch ( $Hi )
{
case 0 : $red = $V; $gre = $t; $blu = $p; break;
case 1 : $red = $q; $gre = $V; $blu = $p; break;
case 2 : $red = $p; $gre = $V; $blu = $t; break;
case 3 : $red = $p; $gre = $q; $blu = $V; break;
case 4 : $red = $t; $gre = $p; $blu = $V; break;
case 5 : $red = $V; $gre = $p; $blu = $q; break;
default : exit("error -- invalid parameters\n\n");
}
$RGB = array(round($red * 255),round($gre * 255),round($blu * 255)); // We're back to RGB with modified Brightness.
return sprintf("%02X%02X%02X",$RGB[0],$RGB[1],$RGB[2]); // RGB back to HEX
}
What I have here is a function that's supposed to simulate transparency by generating HEX colors on the server side. So, $opacity is supposed to be given in percent % from 0 to 100. At 0% it equals $basecolor and at 100% it's white (255,255,255 or #FFFFFF).
So to visually simulate transparency I'm converting everything to HSB color system and shifting Saturation and Brightness values by a certain percentage and then converting it back to RGB and HEX. =)
Shifting brightness is a no-brainer - it's all linear. But when it gets to Saturation - that's where I can't figure it out. According to Photoshop it shifts saturation values by using some kind of non-linear function. I can get saturation values from Photoshop at any $opacity. So for instance:
I took opacity values of 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 percent and generated saturation values of different colors in Photoshop with these opacities (consecutively):
If the base color saturation of a color is 83, then the values are 83, 71, 61, 50, 41, 33, 25, 18, 12, 5, 0
Base saturation 56: 56, 42, 33, 24, 19, 14, 10, 7, 4, 2, 0
Base saturation 100: 100, 81, 66, 53, 42, 33, 25, 17, 11, 5, 0
All of the saturation values are % as well (from 1 to 100) if that makes any difference. I'm thinking if I take the last set of numbers (with highest possible saturation 100) and use it as a model...
So as you see it's some kind of a parabolic function. I can't figure out how to create a universal formula that will spit out a modified saturation value according to this parabola if you feed the original saturation value and $opacity into it.
Any ideas? =)
Thanks a bunch in advance! =)