代码之家  ›  专栏  ›  技术社区  ›  Frustrated programmer

如何从基于X&Y坐标的色轮中获取颜色值?

  •  0
  • Frustrated programmer  · 技术社区  · 7 年前


    我是通过一个移动应用程序的NativeScript制作的。我想知道如何得到RGB 因为我两个都可以用 )只使用X/Y坐标?

    {x:0,y:0}

    色轮是一个预先制作的图像,而不是我用画布自动生成它时,任何应用程序被使用。

    color wheel

    3 回复  |  直到 7 年前
        1
  •  2
  •   RobG    7 年前

    使用MS-PowerPoint中的色轮(因为它是可用的),通过将圆除以3120来计算值° 以0为中心的宽段°, 120° 和240° 分别为红色、绿色和蓝色。

    这就产生了相邻颜色的混合,相反颜色的混合是基于距离中心的距离。

    这个映射方案不适用于RGB,因为它是一个三维空间,但是如果坐标用于图像,它会给出HSV的3个维度中的2个 色调 饱和 和一个相邻的滑块 价值 . 为了简单起见,下面只使用一个带有 价值 设置为1。

    Hand-coding a color wheel with canvas .

    /* Convert radians to degrees.
     *
     * @param {number} rad - radians to convert, expects
     *                       rad in range +/- PI per Math.atan2
     * @returns {number} degrees equivalent of rad
     */
    function rad2deg(rad) {
      return (360 + 180 * rad / Math.PI) % 360;
    }
    
    /* Convert h,s,v values to r,g,b
     * See: https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSV
     *
     * @param {number} hue - in range [0, 360]
     * @param {number} saturation - in range 0 to 1
     * @param {number} value - in range 0 to 1
     * @returns {Array|number} [r, g,b] in range 0 to 255
     */
    function hsv2rgb(hue, saturation, value) {
      hue /= 60;
      let chroma = value * saturation;
      let x = chroma * (1 - Math.abs((hue % 2) - 1));
      let rgb = hue <= 1? [chroma, x, 0]:
                hue <= 2? [x, chroma, 0]:
                hue <= 3? [0, chroma, x]:
                hue <= 4? [0, x, chroma]:
                hue <= 5? [x, 0, chroma]:
                          [chroma, 0, x];
    
      return rgb.map(v => (v + value - chroma) * 255);
    }
    
    /* Convert cartesian coordinates to RGB
     * Converts: x, y to polar (radial_distance, angle), then
     *           polar to HSV, then
     *           HSV to RGB
     *
     * @param {number} x - x coordinate in range -1 to 1
     * @param {number} y - y coordinate in range -1 to 1
     * @returns {Array|number} [red, green, blue] values in range 0 to 255
     */
    function rectToRGB(x, y) {
      // Hue is from angle, saturation from distance from centre, value set to 1
      var r = Math.sqrt(x*x + y*y);
      // Limit extent to disc
      var sat = r > 1? 0 : r;
      var hsv = [rad2deg(Math.atan2(y, x)), sat, 1];
      var rgb = hsv2rgb(...hsv).map(Math.round);
      return rgb;
    }
    
    function posToColour(evt) {
      var node = this;
      var originOffset = node.width / 2;
      var offsetLeft = offsetTop = 0;
      
      do {
        offsetLeft += node.offsetLeft;
        offsetTop  += node.offsetTop;
        node = node.offsetParent;
      } while (node.offsetParent)
        
      // Adjust coordinates then scale to range -1 to 1
      var x = ((evt.x - offsetLeft - originOffset) / originOffset).toFixed(2);
      var y = ((originOffset - evt.y + offsetTop) / originOffset).toFixed(2);
    
      var rgb = rectToRGB(x, y);
      
      var patch = document.getElementById('colorPatch');
      patch.style.backgroundColor = `rgb(${rgb.join()})`;
      document.getElementById('data').innerHTML = 
        `x, y : ${(x<0?'':' ')+x}, ${(y<0?'':' ')+y}<br>r,g,b: ${rgb.map(x=>('  '+x).slice(-3)).join(', ')}`;
    }
    
    document.addEventListener('DOMContentLoaded', function() {
      document.getElementById('colourDisc').addEventListener('mousemove', posToColour, false);
    }, false);
    img {width:200px;height:200px;}
    div {width: 90px; height: 90px}
    <table>
     <tr>
       <td><img src="https://i.stack.imgur.com/lPPOO.png" id="colourDisc"></td>
       <td><div id="colorPatch"></div>
           <div><pre id="data"></pre></div></td>
    </table>

    这个 是从原来的一些缩小,但我认为这是更清楚的更短,在风险过度使用:?接线员。

        2
  •  0
  •   Andres Cardona    7 年前

    你似乎排除了一些细节,我会假设你已经有一个坐标转换器方法或什么的,我知道你有一个画布,因此你有画布api和图像数据。

    function getRGB(x, y, canvas) {
      let context = canvas.getContext('2d');
      let [red, green, blue, alpha] = context.getImageData(x, y, 1, 1).data;
      return {red, green, blue, alpha};
    } 
    
        3
  •  -1
  •   Stakvino    7 年前