2013-12-06 3 views
3

Кто-нибудь знает функцию PHP (для> 5.3), которая может преобразовывать цвет HSL в RGB или Hex? Я пробовал десяток поисков Google, и ни одна из функций, которые я нашел, не работает должным образом.Функция PHP для преобразования HSL в RGB или Hex

Не имеет значения, преобразуется ли функция в RGB или hex, потому что преобразование между этими двумя тривиальными. Входы представляют собой значения HSL для CSS (Hue: 0-360, Saturation: 0-100, Lightness: 0-100).

Edit: Определение формата ввода и вывода будет бонус :)

+0

Итак, что случилось с материалом, который вы нашли? Вы уверены, что не пытались использовать их так, как этого не ожидали? – enhzflep

+1

http://stackoverflow.com/q/3597417/505722 – Jim

+0

Возможно, вам придется написать свою собственную функцию, но вот шаблон из соответствующего ответа: http://stackoverflow.com/questions/11804027/farbtastic-convert- hsl-back-to-rgb-or-hex? rq = 1 –

ответ

4

Taking код одного из ответов в связи комментария Джима (PHP HSV to RGB formula comprehension), мы можем вычислить его следующим образом:

<?php  
    $hue = 209; 
    $sat = 75; 
    $lum = 60; 

    $hue /= 360; 
    $sat /= 100; 
    $lum /= 100; 

    $result = ColorHSLToRGB($hue, $sat, $lum); 
    var_dump($result); echo '<br>'; 
    printf("rgb = %d,%d,%d<br>", $result['r'], $result['g'], $result['b']); 




function ColorHSLToRGB($h, $s, $l){ 

     $r = $l; 
     $g = $l; 
     $b = $l; 
     $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s); 
     if ($v > 0){ 
       $m; 
       $sv; 
       $sextant; 
       $fract; 
       $vsf; 
       $mid1; 
       $mid2; 

       $m = $l + $l - $v; 
       $sv = ($v - $m)/$v; 
       $h *= 6.0; 
       $sextant = floor($h); 
       $fract = $h - $sextant; 
       $vsf = $v * $sv * $fract; 
       $mid1 = $m + $vsf; 
       $mid2 = $v - $vsf; 

       switch ($sextant) 
       { 
        case 0: 
          $r = $v; 
          $g = $mid1; 
          $b = $m; 
          break; 
        case 1: 
          $r = $mid2; 
          $g = $v; 
          $b = $m; 
          break; 
        case 2: 
          $r = $m; 
          $g = $v; 
          $b = $mid1; 
          break; 
        case 3: 
          $r = $m; 
          $g = $mid2; 
          $b = $v; 
          break; 
        case 4: 
          $r = $mid1; 
          $g = $m; 
          $b = $v; 
          break; 
        case 5: 
          $r = $v; 
          $g = $m; 
          $b = $mid2; 
          break; 
       } 
     } 
     return array('r' => $r * 255.0, 'g' => $g * 255.0, 'b' => $b * 255.0); 
} 
?> 

Выход:

array(3) { ["r"]=> float(76.5) ["g"]=> float(155.55) ["b"]=> float(229.5) } 
rgb = 76,155,229 
+0

Спасибо, что поставили это вместе. Я использовал его на одном из моих сайтов и, похоже, работал, потому что в любом случае я использовал случайные цвета. Тем не менее, я заметил, что если я просто просматриваю значения оттенков от 0 до 359, я также получаю полностью случайные числа. Является ли эта функция действительно правильной? –

+0

Без проблем, пожалуйста. Yup, тогда как связь между hsl и rgb совершенно неинтуитивная и плавно меняющаяся H, при сохранении значений S и L вызывает резкое изменение значений rgb. Поиграйте с программой редактирования изображений и перетащите пипетку над рисунком образца выбора цвета hsl - значения rgb будут меняться точно так же. ;) - ive использовал этот код в течение многих лет для их создания. – enhzflep

+0

Это действительно странно. Я действительно вижу, что большинство результатов Google для HSL для RGB кажутся странными для эзотерических почти. Но когда я нахожусь в инспекторе Chrome, нажмите на настройку цвета CSS и переключитесь на HSL, я могу просто щелкнуть от 0 до 359 и получить именно то, что ожидаю: я постоянно перехожу через все колесо цвета. Что случилось? –

-1

Если у вас есть значения RGB десятичные (enhzflep показано, как получить их), вы можете легко получить #ab01cd шестигранную веб строку:

$rgb['r'] = ($t = round($rgb['r'] * 255, 0)) < 15 ? '0'.dechex($t) : dechex($t); 
$rgb['g'] = ($t = round($rgb['g'] * 255, 0)) < 15 ? '0'.dechex($t) : dechex($t); 
$rgb['b'] = ($t = round($rgb['b'] * 255, 0)) < 15 ? '0'.dechex($t) : dechex($t); 
$hexweb = "#".$rgb['r'].$rgb['g'].$rgb['b']; 
+0

Это потенциально полезно, когда он получает RGB, но он не отвечает на вопрос. Btw, это можно упростить до '' # '. Str_pad (dechex (($ r << 16) + ($ g << 8) + $ b), 6,' 0 ', STR_PAD_LEFT); ' –

2

Сведя вместе (который помог мне произвести this chart)

/** 
* convert a HSL colorscheme to either Hexadecimal (default) or RGB. 
* 
* We want a method where we can programmatically generate a series of colors 
* between two values (eg. red to green) which is easy to do with HSL because 
* you just change the hue. (0 = red, 120 = green). You can use this function 
* to convert those hsl color values to either the rgb or hexadecimal color scheme. 
* e.g. You have 
* hsl(50, 100%, 50%) 
* To convert, 
* $hex = convertHSL(50,100,50); // returns #ffd500 
* or 
* $rgb = convertHSL(50,100,50, false); // returns rgb(255, 213, 0) 
* 
* see https://coderwall.com/p/dvsxwg/smoothly-transition-from-green-to-red 
* @param int $h the hue 
* @param int $s the saturation 
* @param int $l the luminance 
* @param bool $toHex whether you want hexadecimal equivalent or rgb equivalent 
* @return string usable in HTML or CSS 
*/ 

function convertHSL($h, $s, $l, $toHex=true){ 
    $h /= 360; 
    $s /=100; 
    $l /=100; 

    $r = $l; 
    $g = $l; 
    $b = $l; 
    $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s); 
    if ($v > 0){ 
      $m; 
      $sv; 
      $sextant; 
      $fract; 
      $vsf; 
      $mid1; 
      $mid2; 

      $m = $l + $l - $v; 
      $sv = ($v - $m)/$v; 
      $h *= 6.0; 
      $sextant = floor($h); 
      $fract = $h - $sextant; 
      $vsf = $v * $sv * $fract; 
      $mid1 = $m + $vsf; 
      $mid2 = $v - $vsf; 

      switch ($sextant) 
      { 
       case 0: 
         $r = $v; 
         $g = $mid1; 
         $b = $m; 
         break; 
       case 1: 
         $r = $mid2; 
         $g = $v; 
         $b = $m; 
         break; 
       case 2: 
         $r = $m; 
         $g = $v; 
         $b = $mid1; 
         break; 
       case 3: 
         $r = $m; 
         $g = $mid2; 
         $b = $v; 
         break; 
       case 4: 
         $r = $mid1; 
         $g = $m; 
         $b = $v; 
         break; 
       case 5: 
         $r = $v; 
         $g = $m; 
         $b = $mid2; 
         break; 
      } 
    } 
    $r = round($r * 255, 0); 
    $g = round($g * 255, 0); 
    $b = round($b * 255, 0); 

    if ($toHex) { 
     $r = ($r < 15)? '0' . dechex($r) : dechex($r); 
     $g = ($g < 15)? '0' . dechex($g) : dechex($g); 
     $b = ($b < 15)? '0' . dechex($b) : dechex($b); 
     return "#$r$g$b"; 
    } else { 
     return "rgb($r, $g, $b)";  
    } 
0

Вот мое решение

ограничения значений HSV: $ H [0-359], $ S [0-100], $ V [0-100]

function hsv_to_rgb($iH, $iS, $iV) { 

    if($iH < 0) $iH = 0; 
    if($iH > 360) $iH = 360; 
    if($iS < 0) $iS = 0; 
    if($iS > 100) $iS = 100; 
    if($iV < 0) $iV = 0; 
    if($iV > 100) $iV = 100; 
    $dS = $iS/100.0; 
    $dV = $iV/100.0; 
    $dC = $dV*$dS; 
    $dH = $iH/60.0; 
    $dT = $dH; 
    while($dT >= 2.0) $dT -= 2.0; // php modulus does not work with float 
    $dX = $dC*(1-abs($dT-1));  // as used in the Wikipedia link 
    switch($dH) { 
     case($dH >= 0.0 && $dH < 1.0): 
     $dR = $dC; $dG = $dX; $dB = 0.0; break; 
     case($dH >= 1.0 && $dH < 2.0): 
     $dR = $dX; $dG = $dC; $dB = 0.0; break; 
     case($dH >= 2.0 && $dH < 3.0): 
     $dR = 0.0; $dG = $dC; $dB = $dX; break; 
     case($dH >= 3.0 && $dH < 4.0): 
     $dR = 0.0; $dG = $dX; $dB = $dC; break; 
     case($dH >= 4.0 && $dH < 5.0): 
     $dR = $dX; $dG = 0.0; $dB = $dC; break; 
     case($dH >= 5.0 && $dH < 6.0): 
     $dR = $dC; $dG = 0.0; $dB = $dX; break; 
     default: 
     $dR = 0.0; $dG = 0.0; $dB = 0.0; break; 
    } 
    $dM = $dV - $dC; 
    $dR += $dM; $dG += $dM; $dB += $dM; 
    $dR *= 255; $dG *= 255; $dB *= 255; 
    return array(round($dR), round($dG), round($dB)); 
    } 
0

Мои тесты всех других реализаций показали только странные и, возможно, неправдоподобные результаты. Вот PHP-реализация кода @ Mohsen от https://stackoverflow.com/a/9493060/1598477. Плюс тест, чтобы показать полную красоту ...

Извините, что перекрестите это. Но я действительно не видел никакой другой реализации, которая давала качество, в котором я нуждался.

/** 
* Converts an HSL color value to RGB. Conversion formula 
* adapted from http://en.wikipedia.org/wiki/HSL_color_space. 
* Assumes h, s, and l are contained in the set [0, 1] and 
* returns r, g, and b in the set [0, 255]. 
* 
* @param {number} h  The hue 
* @param {number} s  The saturation 
* @param {number} l  The lightness 
* @return {Array}   The RGB representation 
*/ 

function hue2rgb($p, $q, $t){ 
      if($t < 0) $t += 1; 
      if($t > 1) $t -= 1; 
      if($t < 1/6) return $p + ($q - $p) * 6 * $t; 
      if($t < 1/2) return $q; 
      if($t < 2/3) return $p + ($q - $p) * (2/3 - $t) * 6; 
      return $p; 
     } 
function hslToRgb($h, $s, $l){ 
    if($s == 0){ 
     $r = $l; 
     $g = $l; 
     $b = $l; // achromatic 
    }else{ 
     $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s; 
     $p = 2 * $l - $q; 
     $r = hue2rgb($p, $q, $h + 1/3); 
     $g = hue2rgb($p, $q, $h); 
     $b = hue2rgb($p, $q, $h - 1/3); 
    } 

    return array(round($r * 255), round($g * 255), round($b * 255)); 
} 

/* Uncomment to test */
for ($i=0;$i<360;$i++) { 
    $rgb=hslToRgb($i/360, 1, .9); 
    echo '<div style="background-color:rgb(' .$rgb[0] . ', ' . $rgb[1] . ', ' . $rgb[2] . ');padding:2px;"></div>'; 
} 
/* End Test */ 
Смежные вопросы