23

スペクトルカラー範囲全体でRGBカラーの範囲を等間隔にするにはどうすればよいですか?本物の虹のように見えるように。

4

8 に答える 8

18

HSV色空間を使用して、色相の次元を歩くことができます。

于 2009-07-31T10:04:28.593 に答える
18

代わりにHSLを使用してください。明るさと彩度を修正し、色相を0から360に変更してから、RGBに変換します。

HSLは、人々が知覚する色を表します。RGBは、それらがマシンで使用されるときにそれらを記述します。したがって、RGBを使用して視覚的に心地よいものを直接実行することはできません。

于 2009-07-31T10:02:25.773 に答える
8

最も簡単なアプローチは、このシーケンスの連続する各ペア間で線形補間(RGB)を実行することです。

  • #ff0000
  • #ffff00黄色
  • #00ff00
  • #00ffffシアン
  • #0000ff
  • #ff00ff赤紫色
  • #ff0000赤に戻る

これにより、HSVまたはHSLの色相値をスイープするのとほぼ同じ結果が得られますが、RGBで直接作業することができます。補間ごとに1つのコンポーネントのみが変更されることに注意してください。これにより、作業が簡素化されます。Pythonの実装は次のとおりです。

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
于 2009-07-31T10:23:39.833 に答える
2

他のソリューションは、かなり大量のコードと条件付き分岐を必要とするため、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++17バージョンです:

std::array<float, 3> HueToRGB(float hue, float *rgb) {
  std::array<float, 3> rgb;
  for (unsigned i = 0; i < 3; ++i) {
    const float h = hue + i / 3.f;
    rgb[i] = std::clamp(6.f * std::fabs(h - std::floor(h) - 0.5f) - 1.f, 0.f, 1.f);
  }
  return rgb;
}

ここで重要なのは、色相値の関数であるR、G、Bの各座標のグラフが周期三角形関数のクランプされた値であり、のこぎり波関数の絶対値として取得できることを理解することx - floor(x)です。

于 2016-01-07T19:25:23.093 に答える
1

このクラスはPHPでそれを行い、コンストラクターに虹に必要な色の数を渡し、$sequenceプロパティにはrrggbb16進コードの配列が含まれます。

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";

私はこれをクラスにパッケージ化したことについてのみクレジットを主張します。元の関数はこの投稿で見つかりました: PHPHSVからRGBへの数式の理解

于 2011-04-19T21:17:01.587 に答える
1
  • 赤(ウェブカラー)(16進数:#FF0000)(RGB:255、0、0)
  • オレンジ(カラーホイールオレンジ)(16進数:#FF7F00)(RGB:255、127、0)
  • 黄色(ウェブカラー)(16進数:#FFFF00)(RGB:255、255、0)
  • 緑(X11)(電気緑)(HTML / CSS「ライム」)(カラーホイール緑)(六角:#00FF00)(RGB:0、255、0)
  • 青(ウェブカラー)(16進数:#0000FF)(RGB:0、0、255)
  • インディゴ(エレクトリックインディゴ)(16進数:#6600FF)(RGB:102、0、255)
  • バイオレット(エレクトリックバイオレット)(16進数:#8B00FF)(RGB:139、0、255)

各色の間で線形補間を行います。

于 2009-07-31T10:06:50.337 に答える
0

私はそれがかなり古い質問であることを知っていますが、これが私のシンプルで理解しやすい解決策であり、ほとんどのプログラミング言語で使いやすいはずです。ステップとwhichStepを独自の値に置き換えます。

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;
}
于 2015-05-28T12:48:44.623 に答える
-1

JavaScriptとHTML5を使ってプログラムで虹を描くことができます。

RainbowVis-レインボーアークを使用したJSの例

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ライブラリ(グラデーションをチェーンするだけ)を使用して、グラデーションに沿った16進カラー値を計算します。HTML5 Canvasを使用して円弧のを描き、色をループさせます。

<!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>
于 2012-02-29T02:55:52.710 に答える