문제

스펙트럼 색상 범위에서 다양한 RGB 색상을 고르게 간격으로 만드는 방법은 무엇입니까? 진짜 무지개처럼 보이도록.

도움이 되었습니까?

해결책

대신 HSL을 사용하십시오 : 밝기와 채도를 고정하고 색조를 0에서 360까지 변경 한 다음 RGB로 변환하십시오.

HSL은 사람들이 인식하는 색상을 설명합니다. RGB는 기계가 사용하는 것으로 설명합니다. 따라서 RGB를 사용하여 직접 시각적으로 유쾌한 일을 할 수는 없습니다.

다른 팁

당신은 사용할 수 있습니다 HSV 색상 공간 색조 차원을 가로 질러 걸어갑니다.

가장 간단한 접근법은이 순서에서 각 연속 쌍 사이에서 선형 보간 (RGB)을 수행하는 것입니다.

  • #ff0000 빨간색
  • #ffff00 노란색
  • #00ff00 초록
  • #00ffff 시안
  • #0000ff 푸른
  • #ff00ff 마젠타
  • #ff0000 다시 빨간색으로

이를 통해 HSV 또는 HSL의 색조 값을 쓸어내는 것과 거의 동일한 결과를 얻을 수 있지만 RGB에서 직접 작업 할 수 있습니다. 각 보간에 대해 하나의 구성 요소 만 변경하여 사물을 단순화합니다. 파이썬 구현은 다음과 같습니다.

def rainbow():
  r, g, b = 255, 0, 0
  for g in range(256):
    yield r, g, b
  for r in range(255, -1, -1):
    yield r, g, b
  for b in range(256):
    yield r, g, b
  for g in range(255, -1, -1):
    yield r, g, b
  for r in range(256):
    yield r, g, b
  for b in range(255, -1, -1):
    yield r, g, b
  • 빨간색 (웹 색상) (16 진 : #FF0000) (RGB : 255, 0, 0)
  • 오렌지 (컬러 휠 오렌지) (16 진수 : #FF7F00) (RGB : 255, 127, 0)
  • 노란색 (웹 색상) (16 진수 : #FFFF00) (RGB : 255, 255, 0)
  • 녹색 (x11) (전기 녹색) (HTML/CSS“라임”) (컬러 휠 그린) (16 진수 : #00ff00) (RGB : 0, 255, 0)
  • 파란색 (웹 색상) (hex : #0000ff) (RGB : 0, 0, 255)
  • Indigo (Electric Indigo) (Hex : #6600ff) (RGB : 102, 0, 255)
  • 바이올렛 (전기 바이올렛) (16 진수 : #8b00ff) (RGB : 139, 0, 255)

각 색상 사이에서 선형 보간을 만듭니다.

이 클래스는 PHP로 수행하고 레인보우에서 원하는 색상 수를 생성자에게 전달하며 $ 시퀀스 속성에는 RRGGBB HEX 코드 배열이 포함됩니다.

class color
{
    public $sequence = array();

    /**
     * constructor fills $sequence with a list of colours as long as the $count param
     */
    public function __construct($count, $s = .5, $l = .5)
    {
        for($h = 0; $h <= .85; $h += .85/$count)    //.85 is pretty much in the middle of the violet spectrum
        {
            $this->sequence[] = color::hexHSLtoRGB($h, $s, $l);
        }
    }

    /**
     * from https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension#3642787
     */
    public static function HSLtoRGB($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' => floor($r * 255.0),
                    'g' => floor($g * 255.0), 
                    'b' => floor($b * 255.0)
                    );
    }

    //return a hex code from hsv values
    public static function hexHSLtoRGB($h, $s, $l)
    {
        $rgb = self::HSLtoRGB($h, $s, $l);
        $hex = base_convert($rgb['r'], 10, 16) . base_convert($rgb['g'], 10, 16) . base_convert($rgb['b'], 10, 16);
        return $hex;
    }
}

예를 들어 테스트하려면 :

$c = new color(100);
foreach($c->sequence as $col)
  print "<div style='background-color:#$col'>$col</div>\n";

나는 이것을 클래스에 포장 한 것에 대한 크레딧 만 주장하고, 원래 기능은이 게시물에서 발견되었습니다.PHP HSV에서 RGB 공식 이해력

다른 솔루션은 다소 많은 양의 코드 및 조건부 분기가 필요하므로 GPU에 적합하지 않습니다. 나는 최근 GLSL에서 다음 마술처럼 간단한 공식에 도착했습니다. OpenCL에서 본질적으로 동일합니다.

vec3 HueToRGB(float hue) {
  vec3 h = vec3(hue, hue + 1.0/3.0, hue + 2.0/3.0);
  return clamp(6.0 * abs(h - floor(h) - 0.5) - 1.0, 0.0, 1.0);
}

이것은 선형 RGB의 주어진 색조 값에 해당하는 무지개 색상을 제공합니다. 이미지에서 사용하려면 SRGB로 변환 한 다음 255를 곱하십시오.

다음은 C ++ 버전입니다.

float clamp(float value, float low, float high) {
  return value < low ? low : (value > high ? high : value);
}
void HueToRGB(float hue, float *rgb) {
  rgb[0] = hue;
  rgb[1] = hue + 1.f/3.f;
  rgb[2] = hue + 2.f/3.f;
  for (unsigned i = 0; i < 3; ++i) {
    rgb[i] = clamp(6.0f * fabsf(rgb[i] - floorf(rgb[i]) - 0.5f) - 1.f, 0.f, 1.f);
  }
}

여기서 핵심은 HUE 값의 함수에서 각 R, G, B 좌표의 그래프가주기적인 삼각형 함수의 클램핑 값이며 톱니 기능의 절대 값으로 얻을 수 있음을 인식하는 것입니다. x - floor(x).

나는 그것이 오래된 질문이라는 것을 알고 있지만 여기에 간단하고 이해하기 쉬운 솔루션이 있습니다. 대부분의 프로그래밍 언어에서 사용하기 쉽습니다. 단계를 바꾸고 자신의 값으로 교체하십시오.

int steps = 1280;
int stepChange = 1280 / steps;
int change = stepChange * whichStep;
int r=0, g=0, b=0;

if (change < 256)
{
    r = 255;
    g += change;
}
else if (change < 512)
{
    r = 511 - change;
    g = 255;
}
else if (change < 768)
{
    g = 255;
    b = change-512;
}
else if (change < 1024)
{
    g = 1023 - change;
    b = 255;
}
else
{
    r = change - 1024;
    b = 255;
}

JavaScript와 HTML5로 프로그래밍 방식으로 무지개를 그릴 수 있습니다.

RainbowVis-JS example with rainbow arc

나는 RGB (255,0,0) -> rgb (255,255,0) -> rgb (0,255,0) -> rgb (0,255,255) -> rgb (0,0,255) -> rgb (255,0,255)의 그라디언트를 만듭니다. ).

나는 내 Rainbowvis-JS 라이브러리 (그라디언트가 함께 체인). 나는 아크를 그립니다 모양 html5 캔버스를 사용하여 색상을 통과합니다.

<!DOCTYPE html>
<html>
  <head>
    <script src="rainbowvis.js"></script>
  </head>
  <body>
    <script type="text/javascript">
      window.onload = function(){

        var RAINBOW_WIDTH = 60;
        var RAINBOW_RADIUS = 130;

        // Library class
        var rainbow = new Rainbow();
        rainbow.setNumberRange(1, RAINBOW_WIDTH);
        rainbow.setSpectrum(
          'FF0000', 'FFFF00', '00FF00',
          '00FFFF', '0000FF', 'FF00FF'
        );

        // Canvas
        var canvas = document.getElementById('MyCanvas');
        var context = canvas.getContext('2d');

        context.lineWidth = 1;
        for (var i = 1; i <= RAINBOW_WIDTH; i++) {
          context.beginPath();
          context.arc(canvas.width/2, canvas.width/2, RAINBOW_RADIUS - i+1, 
            Math.PI, 0, false);
          context.strokeStyle = '#' + rainbow.colourAt(i); // Library function
          context.stroke();
        }
      };
    </script>
    <canvas id="MyCanvas" width="300" height="300">
      <p>Rainbow arc example. Your browser doesn't support canvas.</p>
    </canvas>
  </body>
</html>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top