以编程方式使十六进制颜色(或rgb和混合颜色)变亮或变暗

JavaScript

2020-03-12

这是我正在使用的功能,用于以编程方式使十六进制颜色变亮或变暗特定数量。只需传入一个"3F6D2A"颜色字符串col)和一个amt以10为底的整数()来表示要变亮或变暗的数量。要变暗,请输入负数(即-20)。

我这样做的原因是因为我找到了所有解决方案,到目前为止,它们似乎使问题变得过于复杂。我觉得只需几行代码就可以完成。如果您发现任何问题或进行任何调整以加快速度,请告诉我。

function LightenDarkenColor(col, amt) {
  col = parseInt(col, 16);
  return (((col & 0x0000FF) + amt) | ((((col >> 8) & 0x00FF) + amt) << 8) | (((col >> 16) + amt) << 16)).toString(16);
}


// TEST
console.log( LightenDarkenColor("3F6D2A",40) );

对于开发使用,这里是一个易于阅读的版本:

function LightenDarkenColor(col, amt) {
  var num = parseInt(col, 16);
  var r = (num >> 16) + amt;
  var b = ((num >> 8) & 0x00FF) + amt;
  var g = (num & 0x0000FF) + amt;
  var newColor = g | (b << 8) | (r << 16);
  return newColor.toString(16);
}


// TEST
console.log(LightenDarkenColor("3F6D2A", -40));

最后是处理可能(或可能没有)开头带有“#”的颜色的版本。加上调整不正确的颜色值:

function LightenDarkenColor(col,amt) {
    var usePound = false;
    if ( col[0] == "#" ) {
        col = col.slice(1);
        usePound = true;
    }

    var num = parseInt(col,16);

    var r = (num >> 16) + amt;

    if ( r > 255 ) r = 255;
    else if  (r < 0) r = 0;

    var b = ((num >> 8) & 0x00FF) + amt;

    if ( b > 255 ) b = 255;
    else if  (b < 0) b = 0;

    var g = (num & 0x0000FF) + amt;

    if ( g > 255 ) g = 255;
    else if  ( g < 0 ) g = 0;

    return (usePound?"#":"") + (g | (b << 8) | (r << 16)).toString(16);
}

OK, so now it's not just a couple of lines, but it seems far simpler and if you're not using the "#" and don't need to check for colors out of range, it is only a couple of lines.

If not using the "#", you can just add it in code like:

var myColor = "3F6D2A";
myColor = LightenDarkenColor(myColor,10);
thePlaceTheColorIsUsed = ("#" + myColor);

I guess my main question is, am I correct here? Does this not encompass some (normal) situations?

第1285篇《以编程方式使十六进制颜色(或rgb和混合颜色)变亮或变暗》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

7个回答
null 2020.03.12

我也做了一个简单的包装。我用了IR ^ 3的凸度

为了变暗,我使用了以下内容

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.floor(rgb[i] - ratio * rgb[i]);
}

为了减轻

for (let i = 0; i < rgb.length; i++) {
   rgb[i] = Math.ceil(rgb[i] + ratio * (255 - rgb[i]));
}

这是包https://github.com/MarchWorks/colortone

演示https://colortone.now.sh/

用我做事的方式,如果您通过-1的比率,您将最终得到黑色,如果该比率为1,则最终将为白色。通过0会因为该比率不会改变颜色

null 2020.03.12

使用以下方法可以使十六进制(Hex)颜色字符串的曝光值变亮或变暗:

private static string GetHexFromRGB(byte r, byte g, byte b, double exposure)
{
    exposure = Math.Max(Math.Min(exposure, 1.0), -1.0);
    if (exposure >= 0)
    {
        return "#"
            + ((byte)(r + ((byte.MaxValue - r) * exposure))).ToString("X2")
            + ((byte)(g + ((byte.MaxValue - g) * exposure))).ToString("X2")
            + ((byte)(b + ((byte.MaxValue - b) * exposure))).ToString("X2");
    }
    else
    {
        return "#"
            + ((byte)(r + (r * exposure))).ToString("X2")
            + ((byte)(g + (g * exposure))).ToString("X2")
            + ((byte)(b + (b * exposure))).ToString("X2");
    }

}

对于GetHexFromRGB()中的最后一个参数值,传入一个介于-1和1之间的双精度值(-1是黑色,0不变,1是白色):

// split color (#e04006) into three strings
var r = Convert.ToByte("e0", 16);
var g = Convert.ToByte("40", 16);
var b = Convert.ToByte("06", 16);

GetHexFromRGB(r, g, b, 0.25);  // Lighten by 25%;
乐米亚 2020.03.12

C#版本...请注意,我正在以这种格式#FF12AE34获取颜色字符串,并且需要剪切#FF。

    private string GetSmartShadeColorByBase(string s, float percent)
    {
        if (string.IsNullOrEmpty(s))
            return "";
        var r = s.Substring(3, 2);
        int rInt = int.Parse(r, NumberStyles.HexNumber);
        var g = s.Substring(5, 2);
        int gInt = int.Parse(g, NumberStyles.HexNumber);
        var b = s.Substring(7, 2);
        int bInt = int.Parse(b, NumberStyles.HexNumber);

        var t = percent < 0 ? 0 : 255;
        var p = percent < 0 ? percent*-1 : percent;

        int newR = Convert.ToInt32(Math.Round((t - rInt) * p) + rInt);
        var newG = Convert.ToInt32(Math.Round((t - gInt) * p) + gInt);
        var newB = Convert.ToInt32(Math.Round((t - bInt) * p) + bInt);

        return String.Format("#{0:X2}{1:X2}{2:X2}", newR, newG, newB);
    }
飞云卡卡西 2020.03.12

这是我根据您的功能使用的。我更喜欢使用百分比而不是百分比,因为它对我来说更直观。

例如,200蓝色值的20%与40蓝色值的20%有很大不同。

无论如何,这是我的修改,谢谢您的原始功能。

function adjustBrightness(col, amt) {

    var usePound = false;

    if (col[0] == "#") {
        col = col.slice(1);
        usePound = true;
    }

    var R = parseInt(col.substring(0,2),16);
    var G = parseInt(col.substring(2,4),16);
    var B = parseInt(col.substring(4,6),16);

    // to make the colour less bright than the input
    // change the following three "+" symbols to "-"
    R = R + amt;
    G = G + amt;
    B = B + amt;

    if (R > 255) R = 255;
    else if (R < 0) R = 0;

    if (G > 255) G = 255;
    else if (G < 0) G = 0;

    if (B > 255) B = 255;
    else if (B < 0) B = 0;

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return (usePound?"#":"") + RR + GG + BB;

}
凯阿飞卡卡西 2020.03.12

我想将颜色更改为特定的亮度级别-不管颜色以前是什么亮度-这都是一个简单的JS函数,尽管我确信它可能会更短,但看起来效果很好

function setLightPercentage(col: any, p: number) {
    const R = parseInt(col.substring(1, 3), 16);
    const G = parseInt(col.substring(3, 5), 16);
    const B = parseInt(col.substring(5, 7), 16);
    const curr_total_dark = (255 * 3) - (R + G + B);

    // calculate how much of the current darkness comes from the different channels
    const RR = ((255 - R) / curr_total_dark);
    const GR = ((255 - G) / curr_total_dark);
    const BR = ((255 - B) / curr_total_dark);

    // calculate how much darkness there should be in the new color
    const new_total_dark = ((255 - 255 * (p / 100)) * 3);

    // make the new channels contain the same % of available dark as the old ones did
    const NR = 255 - Math.round(RR * new_total_dark);
    const NG = 255 - Math.round(GR * new_total_dark);
    const NB = 255 - Math.round(BR * new_total_dark);

    const RO = ((NR.toString(16).length === 1) ? "0" + NR.toString(16) : NR.toString(16));
    const GO = ((NG.toString(16).length === 1) ? "0" + NG.toString(16) : NG.toString(16));
    const BO = ((NB.toString(16).length === 1) ? "0" + NB.toString(16) : NB.toString(16));

    return "#" + RO + GO + BO;}
Mandy猴子 2020.03.12

您是否考虑过rgb> hsl转换?然后只是上下移动光度?那就是我要走的路。

快速浏览一些算法后,获得了以下站点。

PHP:http//serennu.com/colour/rgbtohsl.php

Javascript:http : //mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

编辑上面的链接不再有效。您可以查看页面源要点的 git hub

另外,另一个StackOverflow 问题可能是一个不错的地方。


即使这不是OP的正确选择,但以下内容与我最初建议的代码近似。(假设您具有rgb / hsl转换功能)

var SHADE_SHIFT_AMOUNT = 0.1; 

function lightenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.min(hsl[2] + SHADE_SHIFT_AMOUNT, 1);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

function darkenShade(colorValue)
{
    if(colorValue && colorValue.length >= 6)
    {
        var redValue = parseInt(colorValue.slice(-6,-4), 16);
        var greenValue = parseInt(colorValue.slice(-4,-2), 16);
        var blueValue = parseInt(colorValue.slice(-2), 16);

        var hsl = rgbToHsl(redValue, greenValue, blueValue);
        hsl[2]= Math.max(hsl[2] - SHADE_SHIFT_AMOUNT, 0);
        var rgb = hslToRgb(hsl[0], hsl[1], hsl[2]);
        return "#" + rgb[0].toString(16) + rgb[1].toString(16) + rgb[2].toString(16);
    }
    return null;
}

假设:

  1. You have functions hslToRgb and rgbToHsl.
  2. The parameter colorValue is a string in the form #RRGGBB

Although if we are discussing css there is a syntax for specifying hsl/hsla for IE9/Chrome/Firefox.

理查德猿JinJin 2020.03.12

我提出了一个对我来说很好的解决方案:

function shadeColor(color, percent) {

    var R = parseInt(color.substring(1,3),16);
    var G = parseInt(color.substring(3,5),16);
    var B = parseInt(color.substring(5,7),16);

    R = parseInt(R * (100 + percent) / 100);
    G = parseInt(G * (100 + percent) / 100);
    B = parseInt(B * (100 + percent) / 100);

    R = (R<255)?R:255;  
    G = (G<255)?G:255;  
    B = (B<255)?B:255;  

    var RR = ((R.toString(16).length==1)?"0"+R.toString(16):R.toString(16));
    var GG = ((G.toString(16).length==1)?"0"+G.toString(16):G.toString(16));
    var BB = ((B.toString(16).length==1)?"0"+B.toString(16):B.toString(16));

    return "#"+RR+GG+BB;
}

示例减轻:

shadeColor("#63C6FF",40);

示例变暗:

shadeColor("#63C6FF",-40);

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android