JavaScript:根据色调将灰度转换为彩色

4
我有一个灰度色彩,rgb(128, 128, 128),我想找到具有相同亮度的特定色调为0(红色)的颜色,在Javascript中实现。
我知道如何找到灰色的亮度,使用((0.3 * r + 0.59 * g + 0.11 * b)),但我想知道如何给该颜色添加色调。我希望白色保持不变,浅灰色变成浅红色,中灰色变成明亮的红色,深灰色变成暗红色,黑色仍然是黑色等。色调可能会改变。
目前我已经尝试了这个方法,但当给出白色时它会给出明亮的红色而不是白色。
// lightness = 0 - 255
// color = {r: 1, g: 0, b: 0}

newcolor = {};
newcolor.r = lightness * color.r;
newcolor.g = lightness * color.g;
newcolor.b = lightness * color.b;
return newcolor;

你在哪里设置白色?我认为 {r: 1, g: 0, b: 0} 应该是亮红色,而不是白色。 - JJJ
1
你需要使用HSV/HSL颜色空间而不是RGB。这样,你可以通过度数和亮度来选择你的颜色。 - user1693593
我想要能够输入色调,而不是RGB颜色。我输入了一个RGB值,因为那是我能想到的唯一方法来让它基本工作。那个{r:1,g:0,b:0}应该只是红色的0。 - Asraelite
如果您将亮度设置为0-255,则值将为-255,1 * -255 = -255。在RGB中不是有效值。 - Luan Castro
@KenFyrstenberg 我尝试过了,遇到了同样的问题。你可以通过改变亮度值将颜色从黑色变为鲜艳,但一旦亮度值达到255,你需要减少饱和度才能将它们从鲜艳变为白色。我不知道如何根据亮度使用亮度值和饱和度来实现。 - Asraelite
@Asraelite 我更新了我的答案,加入了HSL方法。 - user1693593
1个回答

2

解决方案

你需要使用HSV或HSL颜色空间代替RGB,至少这样可以使事情更容易联系起来。

在被接受后对答案进行更新,以实现对HSL的解决方案,它能够在其标准范围内完成此操作,与HSV相比(很抱歉,我忘记了这个细节作为两者之间的主要区别)。结果是相同的,但是HSL简化了代码。

HSV (旧答案)

为了使用HSV(如下所示)根据亮度进行着色,您只需将用于亮度和饱和度的输入比例扩展到双倍,然后使用阈值来切换所影响的值(HSL将直接执行此操作,请参见下面的更新)。

假设亮度和饱和度从[0,100]变化。然后将输入值扩展为[0,200]。现在制作一个阈值,用于切换其所用的组件:

if (lum > 100) {
    col = hsv2rgb(angle, 100 - (lum - 100), 100);
} else {
    col = hsv2rgb(angle, 100, lum);    
}

现在你的颜色将从黑色变为鲜艳,从鲜艳变为白色。

这里有简单的演示

对于图像中的像素,您只需将亮度值归一化以扩展每个像素的双倍比例。如果您的亮度值在范围[0, 255]内:

lum = luma / 255 * 200;

使用HSV的图片

HSL(新方法)

对于这个特定任务(上色),HSL可能更适合,因为它的整个范围已经像上面的HSV一样完成了,而不需要使用阈值和缩放范围。这也是HSV和HSL之间的主要区别。

以下演示在预灰度图像上使用HSL方法:

使用HSL的图片

演示图片

你选择使用哪种方法可能取决于性能等因素(HSV + 阈值似乎更高效)。

无论如何,这里有一个将HSL转换为RGB的代码片段:

function hsl2rgb(h, s, l) {

    var r, g, b, q, p;

    if (s == 0) {
        r = g = b = l;
    } else {
        function hue2rgb(p, q, t) {
            if (t < 0) t++;
            if (t > 1) t--;
            if (t < 1/6) return p + (q - p) * 6 * t;
            if (t < 1/2) return q;
            if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
            return p;
        }

        q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        p = 2 * l - q;

        r = hue2rgb(p, q, h + 1/3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1/3);
    }

    return {
        r: r * 255,
        g: g * 255,
        b: b * 255};
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接