Xpoint
   [напомнить пароль]

Генератор цветовых шаблонов для любого дизайна

Метки: [без меток]
[арх]
2011-03-29 16:01:49 [обр] Alexander[досье]
сообщение промодерировано

Не знаю как вас, а меня как веб-разработчика неоднократно просили добавить возможность "чуть-чуть" подправить цвет фона или же в проекте была необходимость менять цвет всего интерфейса.

Каждый раз напрягать дизайнера прорисовывать дизайн в разных цветах мне совершенно не нравилось, и я начал думать как можно получить целую гамму оттенков без помощи графических редакторов, а только cредствами PHP.

Сначала я пошел "влоб" и убил пару дней на изучение зависимостей между оттенкам в модели RGB, построил кучу графиков, но это так и не привело ни к чему, что будет не стыдно показать. После этого просмотрев пару статей по теории цвета я занялся изучением модели HSL, где моё внимание и привлек параметр Hue. Благодаря википедии и гуглу были получены 2 функции пересчета из RGB в HSL и обратно соответственно. Не долго думая я начал добавлять константу к параметру Hue и цвет менялся проходя по всей палитре.

Ниже я привожу функции пересчета, а также уже готовые функции вариант для пересчета отдельного цвета в формте RGB, и для обработки png-изображений с поддержкой прозрачности.

function rgb2hsl($r, $g, $b) {
// т.к параметры HSL - это дроби от 0 до 1, то приводим цвета в соответствующий вид
   $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;
//если минимум равен максимуму - значит все значения равны, следовательно мы имеем дело с оттенком серого, для котрого важен только параметр L
   if ($del_Max == 0) {
      $h = 0;
      $s = 0;
   } else {
      $s = $del_Max / $var_Max;
      $del_Max2=$del_Max/2;
      $del_R = ( ( ( $max - $var_R ) / 6 ) + $del_Max2 ) / $del_Max;
      $del_G = ( ( ( $max - $var_G ) / 6 ) + $del_Max2 ) / $del_Max;
      $del_B = ( ( ( $max - $var_B ) / 6 ) + $del_Max2 ) / $del_Max;

      if     ($var_R == $var_Max) $h = $del_B - $del_G;
      elseif ($var_G == $var_Max) $h = 0.333 + $del_R - $del_B;
      elseif ($var_B == $var_Max) $h = 0.667 + $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) { //если насыщенность цвета равно 0, то мы имеем дело с оттенком серого код которого и вычисляем умножая на 255
        $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 ; }
        elseif  ($var_i == 1) { $var_R = $var_2 ; $var_G = $v      ; $var_B = $var_1 ; }
        elseif  ($var_i == 2) { $var_R = $var_1 ; $var_G = $v      ; $var_B = $var_3 ; }
        elseif  ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2  ; $var_B = $v     ; }
        elseif  ($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);
}

function recount($color,$a){
//переводим цвета из шестнадцатеричной системы счисления в десятичную.
$r=hexdec(substr($color,0,2));
$g=hexdec(substr($color,2,2));
$b=hexdec(substr($color,4,2)); 
            list($h, $s, $l) = rgb2hsl($r, $g, $b);
            $h += $a / 360;
            $h-=floor($h); //на случай если получился угол больше 360
            list($r, $g, $b) = hsl2rgb($h, $s, $l); 
//переводим цвета из десятичной системы счисления в шестнадцатеричную.
$r=dechex(round($r));
$g=dechex(round($g));
$b=dechex(round($b));
                //проверяем нет ли однознаковых чисел                        
                if(strlen($r)==1)$r="0".$r;
                if(strlen($g)==1)$g="0".$g;   
                if(strlen($b)==1)$b="0".$b; 
//возвращаем строку цвета в формате RGB
                        return $r.$g.$b;
}

В дополнение к статье привожу скрипт для пересчета картинок, а не отдельных цветов.

<?php

header('Content-type: image/png');
//создаем изображение из уже имеющегося
$image = imagecreatefrompng('./icq1.png');
//создаем новое изображение таких же размеров с прозрачным фоном
$image2=imagecreatetruecolor(imagesx($image),imagesy($image));
imagesavealpha($image2, true);
imagealphablending($image2, true);
$transparent = imagecolorallocatealpha($image2, 255, 255, 255, 127);
imagefill($image2, 0, 0, $transparent);
imagealphablending($image,true);

//запускаем поворот Hue на указанный угол
imagehue($image, $_GET['angle'],$image2);

//выводим изображение
imagepng($image2);

function imagehue(&$image, $angle,&$image2) {

    $width = imagesx($image);
    $height = imagesy($image);
    for($x = 0; $x < $width; $x++) {
        for($y = 0; $y < $height; $y++) {

            $rgb = imagecolorat($image, $x, $y);
                        $alpha=($rgb >> 24) & 0xFF;
                        $r = ($rgb >> 16) & 0xFF;
            $g = ($rgb >> 8) & 0xFF;
            $b = $rgb & 0xFF;    
if((($r==$g)&&($r==$b))||($alpha==127)){imagesetpixel($image2, $x, $y, imagecolorallocatealpha($image, $r, $g, $b,$alpha));}
else{
            list($h, $s, $l) = rgb2hsl($r, $g, $b);
            $h += $angle / 360;
            $h-=floor($h);
            list($r, $g, $b) = hsl2rgb($h, $s, $l);  
            imagesetpixel($image2, $x, $y, imagecolorallocatealpha($image, $r, $g, $b,$alpha));
}
        }
    }
}

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_Max2=$del_Max/2;
      $del_R = ( ( ( $max - $var_R ) / 6 ) + $del_Max2 ) / $del_Max;
      $del_G = ( ( ( $max - $var_G ) / 6 ) + $del_Max2 ) / $del_Max;
      $del_B = ( ( ( $max - $var_B ) / 6 ) + $del_Max2 ) / $del_Max;

      if     ($var_R == $var_Max) $h = $del_B - $del_G;
      elseif ($var_G == $var_Max) $h = 0.333 + $del_R - $del_B;
      elseif ($var_B == $var_Max) $h = 0.667 + $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 ; }
        elseif  ($var_i == 1) { $var_R = $var_2 ; $var_G = $v      ; $var_B = $var_1 ; }
        elseif  ($var_i == 2) { $var_R = $var_1 ; $var_G = $v      ; $var_B = $var_3 ; }
        elseif  ($var_i == 3) { $var_R = $var_1 ; $var_G = $var_2  ; $var_B = $v     ; }
        elseif  ($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);
}
?>

Александр Вихорев

спустя 22 часа [обр] Hopter(0/7)[досье]
Alexander[досье] Спасибо!
Powered by POEM™ Engine Copyright © 2002-2005