使用PHP GD Library更改图像的“HUE”?

时间:2009-12-11 19:39:27

标签: php

我想使用PHP图像处理功能更改图像的“色调”。哪个是正确的过滤器?

注意:我来自Photoshop的背景,所以如果我对“色调”的解释与其他人不同,这就是我的意思......

在photoshop中,您可以使用“Hue”滤镜来更改图像的颜色,而不会实际影响图像的设计。

我目前正在使用下面的功能来重新着色我的图像,但由于它完全重新绘制图像而失去了设计,因此无法满足我的需求。

    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);
    }
    ?>

2 个答案:

答案 0 :(得分:34)

我很确定PHP中没有可以处理色调变化的函数。但是您可以编写自己的函数来执行此操作,以下是更改图像色调的步骤:

  1. 逐像素地遍历图像
  2. 使用imagecolorat()
  3. 获取RGB颜色
  4. 将RGB值转换为HSL值
  5. 更改色调值,仅保留饱和度和亮度(Hue是0到360之间的值)
  6. 将新的HSL值转换回RGB
  7. 更改当前像素的颜色
  8. 实际上这似乎是一个非常有趣的尝试,所以我可能会自己这样做,如果你没有找到任何其他解决方案,可以在这里发布。

    修改

    写了这个函数。要在PHP中更改色调,您需要在RGB和HSL颜色空间之间进行转换的函数以及执行图像遍历的函数。这可能有点难看,但效果很好。在较大的图像上相当慢。

    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));
            }
        }
    }
    

    这是用于转换色彩空间所需的辅助函数,从http://www.actionscript.org/forums/showthread.php3?t=50746无耻地复制并进行了少量更改:

    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);
    }
    

    最后,一个用法示例。此示例打开图像,将其色调移动180°并输出到浏览器:

    header('Content-type: image/png');
    $image = imagecreatefrompng('image.png');
    imagehue($image, 180);
    imagepng($image);
    

    由于色调的角度以度为单位,因此给出0,360,720或360的任意倍数将导致图像无变化。

答案 1 :(得分:0)

您通常会从RGB to HSL颜色空间转换,此时您可以直接操作色调。完成所需后,转换回RGB。