0

是否可以为线性颜色选择器增加包含所有可能的 RGB 颜色(只有红色、绿色、蓝色 - 没有 alpha 值)的线性渐变。

到目前为止,我已经尝试使用以下渐变,但它不包含从rgb(0,0,0)to 的所有值rgb(255,255,255)

var grd = ctx.createLinearGradient(0, 0, width, 0);
grd.addColorStop(0,     'red');
grd.addColorStop(1 / 6, 'orange');
grd.addColorStop(2 / 6, 'yellow');
grd.addColorStop(3 / 6, 'green')
grd.addColorStop(4 / 6, 'aqua');
grd.addColorStop(5 / 6, 'blue');
grd.addColorStop(1,     'purple');

非常感谢任何帮助。

4

3 回答 3

13

不幸的是,你不能。

主要原因是 24 位 RGB 包含 16,777,216 种颜色 (256 3 )。只是为了得到一个估计,您将需要一个 4096 x 4096 像素的屏幕分辨率(当然没有这样的方形屏幕,但对于实际显示器来说,等效屏幕的格式约为 16:9)。

简单地说:在普通屏幕上没有空间放置所有像素。

此外,使用渐变会遇到问题,因为这仅适用于画布的一个方向。您需要在两个方向上绘制颜色,您需要直接手动操作位图。

我的建议是对现有的此类调色板进行屏幕快照并将该图像绘制到画布上。这将量化颜色(这也发生在所有可用的颜色选择器中),但会给你一个接近你需要的颜色的近似值。

另外你可以添加滑块来微调值以及文本框(后者在纯画布中有点复杂,但你可以结合html和画布来实现)。

表示“所有”颜色的近似值可能是这样的(来自下面演示的快照):

下面演示的快照

更新

好的,我保证会回复您关于根据 RGB 值计算位置的问题。从图像中的调色板开始,您可以通过将颜色转换为 HSV 颜色空间来轻松计算位置。

将 RGB 转为 HSV 的函数如下所示:

function rgb2hsv() {

    var rr, gg, bb,

    r = arguments[0] / 255,
    g = arguments[1] / 255,
    b = arguments[2] / 255,
    h, s,

    v = Math.max(r, g, b),
    diff = v - Math.min(r, g, b),
    diffc = function (c) {
        return (v - c) / 6 / diff + 1 / 2;
    };

    if (diff === 0) {
        h = s = 0;

    } else {
        s = diff / v;

        rr = diffc(r);
        gg = diffc(g);
        bb = diffc(b);

        if (r === v) {h = bb - gg}
        else if (g === v) {h = (1 / 3) + rr - bb} 
        else if (b === v) {h = (2 / 3) + gg - rr};
        if (h < 0) {h += 1}
        else if (h > 1) {h -= 1}
    }

    return {
        h: (h * 360 + 0.5) |0,
        s: (s * 100 + 0.5) |0,
        v: (v * 100 + 0.5) |0
    }
};

现在颜色以度数 (0-359)、饱和度 (0-100) 和亮度 (0-100) 表示。

要获得水平位置,您需要做的就是将调色板的宽度除以 360 并乘以 h(色调)。要获得垂直位置,您将调色板分为上部和下部。如果饱和度 < 100 那么你在上半部分,如果 V < 100 那么你在下半部分:

function getPos(canvas, h, s, v) {

var m = canvas.height / 2,
    x = canvas.width / 360 * h,
    y;

if (s === 100 && v === 100) {
    y = m;

} else if (v === 100 && s < 100) {
    y = m / 100 * s;

} else if (s === 100 && v < 100) {
    y = m / 100 * (100 - v) + m;
}

x = (x + 0.5) |0; //convert to integer
y = (y + 0.5) |0;

};

这当然需要您生成的调色板非常准确。

演示

请注意,光标不是根据鼠标位置设置的,而是根据 RGB (HSV) 值设置的。它首先从鼠标位置选择颜色 RGB,然后将其转换为 HSV 并从中计算位置。

调色板是根据窗口大小动态生成的。

同样值得一提的是,对于纯色选择,看起来平滑的渐变的问题在于它们是抖动的。这意味着您可以获得一个明显不在您选择范围内的像素值。

为了在您进行颜色选择时减少此问题,您需要平均从鼠标获得的 x 和 y 位置周围的区域。

于 2013-05-30T16:48:06.857 回答
3

你可能想问问自己你想用这些颜色做什么,为什么。此外,您可能会考虑您将拥有的用户类型以及他们想要对颜色做什么。

正如其他响应者所指出的,RGB 颜色空间是 3 维的。但是映射这三个维度的方法不止一种。还有色相/饱和度/值(HSV)。许多带有颜色选择器的应用程序都有,并排或在单独的选项卡中。

色调,HSV 中的 H,可以被认为是沿着彩虹的位置,从红色开始,#ff0000然后再循环回到红色。这通常表示为沿圆的位置,红色为 0 度/360 度,绿色#00ff00为 120 度,蓝色#0000ff为 240 度。

饱和度是指“颜色中有多少颜色”,100% 饱和度表示全色,0% 饱和度表示单色黑色、白色和灰色。值表示颜色的亮度或暗度,0% 值#000000表示任何色调的黑色,100% 表示全亮度,如果饱和度也是 100%,这将是该色调的全色。

这是 Gimp 颜色选择器的屏幕截图。您可以看到它在红色、绿色和蓝色的滑块上方有色相、饱和度和值的滑块。

Gimp 颜色选择器

Hue 的值范围从 0 到 359 度,Saturation 和 Value 的范围从 0% 到 100%,Red、Green 和 Blue 的范围从 0 到 255(ff十六进制)。三角形围绕彩虹旋转 - 色调值 - 三角形内部显示该特定色调的二维饱和度 - 值颜色空间。您可以玩和试验所有这些变量,并了解 RGB 和 HSV 值如何相互关联。

根据您的应用程序,您可能想看看传统的“网络安全颜色”。这些在 Web 的早期更为重要,当时一切都是新的,浏览器兼容性问题很普遍,网页是在 CRT 屏幕监视器上查看的。“网络安全”颜色最有可能在来自不同供应商的不同屏幕上看起来一致。尽管这不再重要,但它们仍然为几乎任何计算机应用程序上的颜色提供了一个很好的起点,您可以根据需要从中分歧。

“网络安全”颜色是使用 RGB 值的 17 的倍数生成的一组颜色,特别强调 51 的倍数 (3 x 17)。

为什么是17?因为11十六进制等于 16 加 1,或者十进制的 17。255 是 2 的 8 次方减 1,是 17 的 15 倍,或者ff是十六进制数字。这使得 0%, 20%, 40%, 60%, 80% 和 100% 的值很好地适合 0, 51, 102, 153, 204 和 255,它们整齐地用十六进制表示法写成00, 33, 66, 99, cc,和ff

于 2013-05-30T20:18:33.703 回答
1

+1 菲利普在现场。RGB 颜色在 2d 空间中不能很好地表示,因为 rgb 有 3 个必须全部表示的分量。

最接近几何表示所有 rgb 组合的是立方体(这是有道理的,因为立方体有 3 个轴,而 rgb 有 3 个值)。

这是来自维基百科的插图: http ://en.wikipedia.org/wiki/RGB_color_space

在此处输入图像描述

您可以将此作为起点,并使用滑块从前到后显示每个颜色“层”。

于 2013-05-30T16:54:11.403 回答