【问题标题】:Using Native JavaScript to Desaturate a Colour使用原生 JavaScript 去饱和颜色
【发布时间】:2025-12-30 10:35:06
【问题描述】:

我有一个颜色选择器,用户可以在其中指定十六进制颜色。

我还想要一个饱和度滑块,用户可以在其中调整饱和度,并获得新的十六进制颜色作为输出。

有没有办法在 JavaScript 中将饱和度值和十六进制颜色转换为新的十六进制颜色?

所以,比如说我有一个值 #FF0000 和 50(满分 100)的饱和度,我如何从中确定新的十六进制颜色?

我不能为它使用任何库,因为我将它创建为我网站的插件,并且我试图让它尽可能轻。

【问题讨论】:

  • FF == 255 255 的 50% 是多少?
  • 查看这个网站,它有一个带有饱和度滑块的javascript颜色选择器,还有一个源代码链接:hslpicker.com/#9C639B
  • 这很好,但它大量使用了库。我试图让它尽可能轻。
  • 我之前使用过一个名为 pixastic 的 JS 库,用于使用画布对图像进行动态去饱和,也许可以看看该库是如何进行计算的:pixastic.com

标签: javascript colors


【解决方案1】:

http://jsfiddle.net/5sfDQ/

$("#color, #saturation").change(function(){
    updateColor();
});

function updateColor(){
    var col = hexToRgb($("#color").val());
    var sat = Number($('#saturation').val())/100;
    var gray = col.r * 0.3086 + col.g * 0.6094 + col.b * 0.0820;

    col.r = Math.round(col.r * sat + gray * (1-sat));
    col.g = Math.round(col.g * sat + gray * (1-sat));
    col.b = Math.round(col.b * sat + gray * (1-sat));

    var out = rgbToHex(col.r,col.g,col.b);

    $('#output').val(out);

    $('body').css("background",out);
}

function componentToHex(c) {
    var hex = c.toString(16);
    return hex.length == 1 ? "0" + hex : hex;
}

function rgbToHex(r, g, b) {
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

function hexToRgb(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

【讨论】:

  • 如果你在 Chrome 中查看这个演示,你甚至会得到一个颜色选择器和一个滑块。
  • 我将其转换为不使用 jQuery,所以现在对我有用:jsfiddle.net/danhanly/5sfDQ/4
  • 您能解释一下常量 0.3、0.6、0.08 的用法吗?这怎么总是产生灰色?
  • @Hugheth 他们可能不会为每个人提供完美的灰色。它们基于人类的平均视力。更多信息在这里:en.m.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems
【解决方案2】:
function applySat(sat, hex) {
    var hash = hex.substring(0, 1) === "#";

    hex = (hash ? hex.substring(1) : hex).split("");

    var long = hex.length > 3,
        rgb = [],
        i = 0,
        len = 3;

    rgb.push( hex.shift() + (long ? hex.shift() : "") );
    rgb.push( hex.shift() + (long ? hex.shift() : "") );
    rgb.push( hex.shift() + (long ? hex.shift() : "") );

    for( ; i < len; i++ ) {
        if ( !long ) {
            rgb[i] += rgb[i];
        }

        rgb[i] = Math.round( parseInt(rgb[i], 16)/100*sat).toString(16);

      rgb[i] += rgb[i].length === 1 ? rgb[i] : "";
    }

    return (hash ? "#" : "") + rgb.join("");
}

console.log(applySat(50, "#ff0000")); // "#7f0000";
console.log(applySat(50, "ff0000")); // "7f0000";
console.log(applySat(50, "#fed")); // "#7f776f"
console.log(applySat(50, "fed")); // "7f776f"
console.log(applySat(20, "#addfaa")); // "#232d22"

【讨论】:

  • 这不是去饱和,而是变暗。
  • @Shmiddty 嗯.. 以为是吗? .所以是反过来的?
  • 您将颜色变为黑色。你应该把它们变成灰色。有几种不同的方法可以做到这一点。您可以使用 128 作为灰度,也可以根据原始颜色计算灰度(对图像进行去饱和处理时更有用)。
  • 您的解决方案很简单,但不幸的是它没有达到我想要的效果。这不是饱和,只是将其变为黑色。它需要变成灰色。
【解决方案3】:

如果您真的不想使用库,请参阅 mjijackson's RGB to HSL conversion page

复制代码以进行 RGB 十六进制到 HSL(或 HSV)的转换。随着滑块的移动,您需要使用它们在颜色模型之间进行转换以获取饱和度值,对其进行修改,然后返回生成的 rgb 颜色。

注意:HSL and HSV 是标准颜色模型。其他一些答案提出了与这些标准颜色模型不对应的“饱和度”定义。用户会感到困惑,因为替代定义所提供的结果与他们对 GIMP、Photoshop 或其他常见图形应用程序的期望不一致。

【讨论】:

    【解决方案4】:

    真正简单易用的功能,输入您的颜色,并添加您想要去饱和的程度。 它做得很好,但并不完全准确。

        function addSaturation(color, amount){
            var color = color.replace('#', '').split('');
            var letters = '0123456789ABCDEF'.split('');
            for(var i = 0; i < color.length; i++){
                var newSaturation = 0;
                if(letters.indexOf(color[i]) + amount > 15) newSaturation = 15;
                else if(letters.indexOf(color[i]) + amount < 0) newSaturation = 0;
                else newSaturation = letters.indexOf(color[i]) + amount;
                color[i] = letters[newSaturation];
            }
            return "#" + color.join('');
        }
    

    您也可以使用正数或负数。

    【讨论】:

      【解决方案5】:

      您可以利用this solution 中提供的 Javascript 来满足您的需求

      要更改元素的饱和度,请同时移动三个 HEX 值中的每一个,使值更接近 128(256 的一半)。

      background-color: #FF0000; // rgb(255, 0, 0)
      

      到这个...

      background-color: #BF4040; // rgb(191, 64, 64)
      

      【讨论】:

        最近更新 更多