I'd like to change the "hue" of an image using the PHP image processing functions. Which is the correct filter to apply?
Note: I'm from a photoshop background, so in the event my interpretation of "hue" is different from others, here's what I mean...
In photoshop, you can use the "Hue" filter to change the color of an image without actually affecting the design of the image.
I'm currently using the function below to recolor my images, but the function fails to meet my needs due to the fact that it completely repaints the image, losing the design.
function set_theme_color_header($hex)
{
$info = hexToRGB($hex); //utility function that converts hex to rgb
$token = "header.gif";
$img = imagecreatefromgif("header-template.gif";
$color = imagecolorallocate($img, $info["red"], $info["green"], $info["blue"]);
imagecolorset($img, 0, $info["red"], $info["green"], $info["blue"]);
imagegif($img, $token);
}
?>
I'm pretty sure there are no functions in PHP that can handle the change of hue. But you can write your own function to do this, here are the steps to change the image's hue:
Actually this seems quite an interesting thing to try out, so I might just do this myself and post it here if you don't find any other solution.
EDIT
Wrote the function. To change hue in PHP, you'll need functions to transform between RGB and HSL color spaces and a function that does the traversing of the image. This might be a bit ugly but it works nicely. Quite slow on larger images.
function imagehue(&$image, $angle) {
if($angle % 360 == 0) return;
$width = imagesx($image);
$height = imagesy($image);
for($x = 0; $x < $width; $x++) {
for($y = 0; $y < $height; $y++) {
$rgb = imagecolorat($image, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$alpha = ($rgb & 0x7F000000) >> 24;
list($h, $s, $l) = rgb2hsl($r, $g, $b);
$h += $angle / 360;
if($h > 1) $h--;
list($r, $g, $b) = hsl2rgb($h, $s, $l);
imagesetpixel($image, $x, $y, imagecolorallocatealpha($image, $r, $g, $b, $alpha));
}
}
}
Here's the required helper functions for converting color space, shamelessly copied from http://www.actionscript.org/forums/showthread.php3?t=50746 with minor alterations:
function rgb2hsl($r, $g, $b) {
$var_R = ($r / 255);
$var_G = ($g / 255);
$var_B = ($b / 255);
$var_Min = min($var_R, $var_G, $var_B);
$var_Max = max($var_R, $var_G, $var_B);
$del_Max = $var_Max - $var_Min;
$v = $var_Max;
if ($del_Max == 0) {
$h = 0;
$s = 0;
} else {
$s = $del_Max / $var_Max;
$del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
$del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
if ($var_R == $var_Max) $h = $del_B - $del_G;
else if ($var_G == $var_Max) $h = ( 1 / 3 ) + $del_R - $del_B;
else if ($var_B == $var_Max) $h = ( 2 / 3 ) + $del_G - $del_R;
if ($h < 0) $h++;
if ($h > 1) $h--;
}
return array($h, $s, $v);
}
function hsl2rgb($h, $s, $v) {
if($s == 0) {
$r = $g = $B = $v * 255;
} else {
$var_H = $h * 6;
$var_i = floor( $var_H );
$var_1 = $v * ( 1 - $s );
$var_2 = $v * ( 1 - $s * ( $var_H - $var_i ) );
$var_3 = $v * ( 1 - $s * (1 - ( $var_H - $var_i ) ) );
if ($var_i == 0) { $var_R = $v ; $var_G = $var_3 ; $var_B = $var_1 ; }
else if ($var_i == 1) { $var_R = $var_2 ; $var_G = $v ; $var_B = $var_1 ; }
else if ($var_i == 2) { $var_R = $var_1 ; $var_G = $v ; $var_B = $var_3 ; }
else if ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2 ; $var_B = $v ; }
else if ($var_i == 4) { $var_R = $var_3 ; $var_G = $var_1 ; $var_B = $v ; }
else { $var_R = $v ; $var_G = $var_1 ; $var_B = $var_2 ; }
$r = $var_R * 255;
$g = $var_G * 255;
$B = $var_B * 255;
}
return array($r, $g, $B);
}
And finally, an usage example. This example opens an image, shifts its hue by 180° and outputs to the browser:
header('Content-type: image/png');
$image = imagecreatefrompng('image.png');
imagehue($image, 180);
imagepng($image);
As the angle of hue is set in degrees, giving 0, 360, 720 or any multiple of 360 will result in no change to the image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With