【问题标题】:iterating over RGB continuously?连续迭代RGB?
【发布时间】:2015-05-27 14:12:24
【问题描述】:

我正在尝试迭代 RGB 值,以获得连续的色板。 通常,要迭代 3 个值并全部获取它们,您可以像二进制一样进行操作:

r g b 
0 0 0 
0 0 1
0 1 0

但我有一个主要问题。我们需要让他们的订单连续查看,例如,我越过红色,而不是橙色,而不是黄色、绿色等。

我应该使用什么算法或伪代码来按顺序获取它们??

请看附上的这张图片,颜色应该是这样的:

【问题讨论】:

  • 太愚蠢了,它就在我这里展示的图片中:)

标签: c colors rgb


【解决方案1】:

从 255 0 0 开始,然后向上计数 g 到 255 255 0,然后向下计数红色到 0 255 0,然后向上计数蓝色到 0 255 255,然后向下计数绿色到 0 0 255,然后向上计数红色到255 0 255,然后蓝色倒数到 255 0 0。

【讨论】:

  • 哇!谢谢 !那太棒了 !我想知道为什么它在物理上是这样工作的!
  • 我盯着数字看了一会儿,突然想到:D 请接受回答!
【解决方案2】:

您需要的是颜色的线性插值,以实现从一种颜色到另一种颜色的平滑过渡。我会给你一个简单的练习,让你理解所涉及的数学。

红色 = (1, 0, 0)

黄色 = (1, 1, 0)(正好在红色和黄色之间)

绿色 = (0, 1, 0)

首先从红色插值到黄色。由于xz 保持不变,唯一要插入的组件是y。平滑度取决于您从一个极端到另一个极端的止损次数。假设我们停止 = 4

+------------+------------+ |红色 |(1, 0, 0) | +------------+------------+ | |(1, 0.2, 0) | + +------------+ | |(1, 0.4, 0) | + 淡黄色 +------------+ |红色 |(1, 0.6, 0) | + +------------+ | |(1, 0.8, 0) | +------------+------------+ |黄色 |(1, 1, 0) | +------------+------------+ | |(0.8, 1, 0) | + +------------+ | |(0.6, 1, 0) | + 淡黄色 +------------+ |绿色 |(0.4, 1, 0) | + +------------+ | |(0.2, 1, 0) | +------------+------------+ |绿色 |(0, 1, 0) | +------------+------------+

如果你从Red -> Yellow -> Green -> Cyan -> Blue -> Magenta 进行插值,你会得到一条线,一个极端是红色,另一个是洋红色。

现在要创建您在问题中发布的HSV wheel,需要同时进行径向和轴向插值。

色调(或实际颜色)是径向插值的,即基于角度。这里的平滑度(停止)将基于角度而不是距离。

+-------+-------+ |角度° |颜色 | +-------+-------+ |0/360 |红色 | +-------+-------+ |60 |黄色 | +-------+-------+ |120 |绿色 | +-------+-------+ |180 |青色 | +-------+-------+ |240 |蓝色 | +-------+-------+ |300 |洋红色| +-------+-------+

饱和度(鲜艳度)是径向插值的,即基于点到中心的距离。中心是纯白色,而圆周上的点是纯色。

因此,以 0° 角从中心到圆周的线将从中心的白色 (1, 1, 1) 开始,在圆周处以纯红色 (1, 0, 0) 结束。对其他角度也做同样的事情(直到你转回 360/0°),你就会得到你贴的轮子;它实际上是一个来自更大 (HSV) 圆柱体的圆盘,其垂直轴将插入 Lightness(上面链接的 Wikipedia 优秀文章中的图片)。

查看下面的代码以获取 HSV 车轮的实时渲染。

         // REFERENCES
         // http://stackoverflow.com/q/10373695
         // http://stackoverflow.com/a/7541756
         // http://tutorials.jenkov.com/html5-canvas/gradients.html
         // Computer Graphics: From Pixels to Programmable Graphics
         // Hardware by Alexey Boreskov, Evgeniy Shikin

         // from rgb_hsv_lerp workout
         function hsv2rgb(h) {
             var s = 1, v = 1;
             while(h < 0) h += 360;
             while(h >= 360) h -= 360;
             h /= 60;
             var i = Math.floor(h);
             var f = h - i;
             var p = v * (1 - s);
             var q = v * (1 - (s * f));
             var t = v * (1 - (s * (1 - f)));
             rgb = [];
             switch(i) {
                 case 0: rgb[0] = v; rgb[1] = t; rgb[2] = p; break;
                 case 1: rgb[0] = q; rgb[1] = v; rgb[2] = p; break;
                 case 2: rgb[0] = p; rgb[1] = v; rgb[2] = t; break;
                 case 3: rgb[0] = p; rgb[1] = q; rgb[2] = v; break;
                 case 4: rgb[0] = t; rgb[1] = p; rgb[2] = v; break;
                 case 5: rgb[0] = v; rgb[1] = p; rgb[2] = q; break;
             }
             return "rgb(" + Math.floor(255 * rgb[0]) + ","
                           + Math.floor(255 * rgb[1]) + ","
                           + Math.floor(255 * rgb[2]) + ")";
         }

         function plot(ctx, x, y, hue) {
             var cx = 0, cy = 0;
             var xs = [x, -y, -x,  y];
             var ys = [y,  x, -y, -x];

             for (var i = 0; i < 4; ++i) {
                 // linear gradient from start to end of line
                 var grad = ctx.createLinearGradient(0, 0, xs[i], ys[i]);
                 grad.addColorStop(0, "white");
                 // the canvas coordinate system has Y ↓ while math coordinate
                 // has Y ↑, so flip hue too to match standard HSV wheel
                 grad.addColorStop(1, hsv2rgb(-(hue + (90 * i))));
                 ctx.strokeStyle = grad;
                 ctx.beginPath();
                 ctx.moveTo(cx, cy);
                 ctx.lineTo(xs[i], ys[i]);
                 ctx.stroke();
             }
         }

         function draw() {
             var can = document.getElementById('canvas1');
             var ctx = can.getContext('2d');
             var r = can.clientWidth / 2;

             ctx.translate(r, r);
             ctx.lineWidth = 2;

             var x = r, y = 0;
             plot(ctx, x, y, 0);
             // divide 45° by number of iterations to get iteration delta
             // y starts at 0, iteration ends when y = x i.e. x = y = r / √2
             var hue_delta = 45 / Math.floor(r / Math.sqrt(2));
             // Bresenham's circle drawing algorithm, reference book cited above
             var d = 1.25 - r;
             while (x > y) {
               ++y;
                 if (d < 0)
                     d += (2 * y) + 3;
                 else {
                     d += 2 * (y - x) + 5;
                     --x;
                 }
                 var hue = y * hue_delta;
                 plot(ctx, x, y, hue);
                 plot(ctx, y, x, 90 - hue);
             }
             ctx.translate(-r, -r);
         }
    <body onload="draw()">
        <h1>HSV Colour Wheel</h1>
        <canvas id="canvas1" width="300" height="300" />
    </body>

【讨论】:

    【解决方案3】:

    从 HSB 或 HSL 值开始,然后将它们转换为 RGB。

    当您选择亮度 (B) 和饱和度 (S) 时,您可以通过不断更改色相 (H) 的值来获得想要的结果

    如果你用谷歌搜索,你会找到进行转换的公式

    【讨论】:

    • 谢谢,但这对我没有任何意义。我真的不明白该怎么做。
    猜你喜欢
    • 2017-08-08
    • 2017-10-22
    • 1970-01-01
    • 2011-02-01
    • 2018-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    相关资源
    最近更新 更多